blob: 21e5913d12e03f4c8410a9464cd5794c9e5a0c70 [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);
Peter Zijlstra4e857c52014-03-17 18:06:10 +010048 smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
Andre Guedes3e13fa12013-03-27 20:04:56 -030049 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 Padovan6039aa732012-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));
Andrzej Kaczmarekd0455ed2014-05-14 13:43:05 +02001285 if (!conn)
1286 goto unlock;
Andrzej Kaczmarek5a134fa2014-05-09 21:35:28 +02001287
Andrzej Kaczmarekd0455ed2014-05-14 13:43:05 +02001288 switch (sent->type) {
1289 case 0x00:
1290 conn->tx_power = rp->tx_power;
1291 break;
1292 case 0x01:
1293 conn->max_tx_power = rp->tx_power;
1294 break;
1295 }
1296
1297unlock:
Andrzej Kaczmarek5a134fa2014-05-09 21:35:28 +02001298 hci_dev_unlock(hdev);
1299}
1300
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001301static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001302{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001303 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001304
1305 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001306 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001307 return;
1308 }
1309
Andre Guedes89352e72011-11-04 14:16:53 -03001310 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001311}
1312
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001313static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001315 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001318 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001319
1320 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321 if (!cp)
1322 return;
1323
1324 hci_dev_lock(hdev);
1325
1326 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1327
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001328 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329
1330 if (status) {
1331 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001332 if (status != 0x0c || conn->attempt > 2) {
1333 conn->state = BT_CLOSED;
1334 hci_proto_connect_cfm(conn, status);
1335 hci_conn_del(conn);
1336 } else
1337 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338 }
1339 } else {
1340 if (!conn) {
1341 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1342 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001343 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344 conn->link_mode |= HCI_LM_MASTER;
1345 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001346 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347 }
1348 }
1349
1350 hci_dev_unlock(hdev);
1351}
1352
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001353static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001355 struct hci_cp_add_sco *cp;
1356 struct hci_conn *acl, *sco;
1357 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001359 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001360
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001361 if (!status)
1362 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001364 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1365 if (!cp)
1366 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001368 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001370 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001371
1372 hci_dev_lock(hdev);
1373
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001374 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001375 if (acl) {
1376 sco = acl->link;
1377 if (sco) {
1378 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001379
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001380 hci_proto_connect_cfm(sco, status);
1381 hci_conn_del(sco);
1382 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001383 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001384
1385 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386}
1387
Marcel Holtmannf8558552008-07-14 20:13:49 +02001388static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1389{
1390 struct hci_cp_auth_requested *cp;
1391 struct hci_conn *conn;
1392
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001393 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001394
1395 if (!status)
1396 return;
1397
1398 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1399 if (!cp)
1400 return;
1401
1402 hci_dev_lock(hdev);
1403
1404 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1405 if (conn) {
1406 if (conn->state == BT_CONFIG) {
1407 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001408 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001409 }
1410 }
1411
1412 hci_dev_unlock(hdev);
1413}
1414
1415static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1416{
1417 struct hci_cp_set_conn_encrypt *cp;
1418 struct hci_conn *conn;
1419
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001420 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001421
1422 if (!status)
1423 return;
1424
1425 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1426 if (!cp)
1427 return;
1428
1429 hci_dev_lock(hdev);
1430
1431 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1432 if (conn) {
1433 if (conn->state == BT_CONFIG) {
1434 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001435 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001436 }
1437 }
1438
1439 hci_dev_unlock(hdev);
1440}
1441
Johan Hedberg127178d2010-11-18 22:22:29 +02001442static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001443 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001444{
Johan Hedberg392599b2010-11-18 22:22:28 +02001445 if (conn->state != BT_CONFIG || !conn->out)
1446 return 0;
1447
Johan Hedberg765c2a92011-01-19 12:06:52 +05301448 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001449 return 0;
1450
1451 /* Only request authentication for SSP connections or non-SSP
Johan Hedberg264b8b42014-01-08 16:40:39 +02001452 * devices with sec_level MEDIUM or HIGH or if MITM protection
1453 * is requested.
1454 */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001455 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
Johan Hedberg7e3691e2014-05-30 14:45:19 +03001456 conn->pending_sec_level != BT_SECURITY_FIPS &&
Johan Hedberg264b8b42014-01-08 16:40:39 +02001457 conn->pending_sec_level != BT_SECURITY_HIGH &&
1458 conn->pending_sec_level != BT_SECURITY_MEDIUM)
Johan Hedberg392599b2010-11-18 22:22:28 +02001459 return 0;
1460
Johan Hedberg392599b2010-11-18 22:22:28 +02001461 return 1;
1462}
1463
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001464static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001465 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001466{
1467 struct hci_cp_remote_name_req cp;
1468
1469 memset(&cp, 0, sizeof(cp));
1470
1471 bacpy(&cp.bdaddr, &e->data.bdaddr);
1472 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1473 cp.pscan_mode = e->data.pscan_mode;
1474 cp.clock_offset = e->data.clock_offset;
1475
1476 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1477}
1478
Johan Hedbergb644ba32012-01-17 21:48:47 +02001479static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001480{
1481 struct discovery_state *discov = &hdev->discovery;
1482 struct inquiry_entry *e;
1483
Johan Hedbergb644ba32012-01-17 21:48:47 +02001484 if (list_empty(&discov->resolve))
1485 return false;
1486
1487 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001488 if (!e)
1489 return false;
1490
Johan Hedbergb644ba32012-01-17 21:48:47 +02001491 if (hci_resolve_name(hdev, e) == 0) {
1492 e->name_state = NAME_PENDING;
1493 return true;
1494 }
1495
1496 return false;
1497}
1498
1499static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001500 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001501{
1502 struct discovery_state *discov = &hdev->discovery;
1503 struct inquiry_entry *e;
1504
1505 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001506 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1507 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001508
1509 if (discov->state == DISCOVERY_STOPPED)
1510 return;
1511
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001512 if (discov->state == DISCOVERY_STOPPING)
1513 goto discov_complete;
1514
1515 if (discov->state != DISCOVERY_RESOLVING)
1516 return;
1517
1518 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001519 /* If the device was not found in a list of found devices names of which
1520 * are pending. there is no need to continue resolving a next name as it
1521 * will be done upon receiving another Remote Name Request Complete
1522 * Event */
1523 if (!e)
1524 return;
1525
1526 list_del(&e->list);
1527 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001528 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001529 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1530 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001531 } else {
1532 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001533 }
1534
Johan Hedbergb644ba32012-01-17 21:48:47 +02001535 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001536 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001537
1538discov_complete:
1539 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1540}
1541
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001542static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1543{
Johan Hedberg127178d2010-11-18 22:22:29 +02001544 struct hci_cp_remote_name_req *cp;
1545 struct hci_conn *conn;
1546
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001547 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001548
1549 /* If successful wait for the name req complete event before
1550 * checking for the need to do authentication */
1551 if (!status)
1552 return;
1553
1554 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1555 if (!cp)
1556 return;
1557
1558 hci_dev_lock(hdev);
1559
1560 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001561
1562 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1563 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1564
Johan Hedberg79c6c702011-04-28 11:28:55 -07001565 if (!conn)
1566 goto unlock;
1567
1568 if (!hci_outgoing_auth_needed(hdev, conn))
1569 goto unlock;
1570
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001571 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001572 struct hci_cp_auth_requested auth_cp;
1573
1574 auth_cp.handle = __cpu_to_le16(conn->handle);
1575 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1576 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001577 }
1578
Johan Hedberg79c6c702011-04-28 11:28:55 -07001579unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001580 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001581}
1582
Marcel Holtmann769be972008-07-14 20:13:49 +02001583static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1584{
1585 struct hci_cp_read_remote_features *cp;
1586 struct hci_conn *conn;
1587
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001588 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001589
1590 if (!status)
1591 return;
1592
1593 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1594 if (!cp)
1595 return;
1596
1597 hci_dev_lock(hdev);
1598
1599 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1600 if (conn) {
1601 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001602 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001603 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001604 }
1605 }
1606
1607 hci_dev_unlock(hdev);
1608}
1609
1610static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1611{
1612 struct hci_cp_read_remote_ext_features *cp;
1613 struct hci_conn *conn;
1614
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001615 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001616
1617 if (!status)
1618 return;
1619
1620 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1621 if (!cp)
1622 return;
1623
1624 hci_dev_lock(hdev);
1625
1626 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1627 if (conn) {
1628 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001629 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001630 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001631 }
1632 }
1633
1634 hci_dev_unlock(hdev);
1635}
1636
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001637static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1638{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001639 struct hci_cp_setup_sync_conn *cp;
1640 struct hci_conn *acl, *sco;
1641 __u16 handle;
1642
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001643 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001644
1645 if (!status)
1646 return;
1647
1648 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1649 if (!cp)
1650 return;
1651
1652 handle = __le16_to_cpu(cp->handle);
1653
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001654 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001655
1656 hci_dev_lock(hdev);
1657
1658 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001659 if (acl) {
1660 sco = acl->link;
1661 if (sco) {
1662 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001663
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001664 hci_proto_connect_cfm(sco, status);
1665 hci_conn_del(sco);
1666 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001667 }
1668
1669 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001670}
1671
1672static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1673{
1674 struct hci_cp_sniff_mode *cp;
1675 struct hci_conn *conn;
1676
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001677 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001678
1679 if (!status)
1680 return;
1681
1682 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1683 if (!cp)
1684 return;
1685
1686 hci_dev_lock(hdev);
1687
1688 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001689 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001690 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001691
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001692 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001693 hci_sco_setup(conn, status);
1694 }
1695
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001696 hci_dev_unlock(hdev);
1697}
1698
1699static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1700{
1701 struct hci_cp_exit_sniff_mode *cp;
1702 struct hci_conn *conn;
1703
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001704 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001705
1706 if (!status)
1707 return;
1708
1709 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1710 if (!cp)
1711 return;
1712
1713 hci_dev_lock(hdev);
1714
1715 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001716 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001717 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001718
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001719 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001720 hci_sco_setup(conn, status);
1721 }
1722
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001723 hci_dev_unlock(hdev);
1724}
1725
Johan Hedberg88c3df12012-02-09 14:27:38 +02001726static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1727{
1728 struct hci_cp_disconnect *cp;
1729 struct hci_conn *conn;
1730
1731 if (!status)
1732 return;
1733
1734 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1735 if (!cp)
1736 return;
1737
1738 hci_dev_lock(hdev);
1739
1740 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1741 if (conn)
1742 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001743 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001744
1745 hci_dev_unlock(hdev);
1746}
1747
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001748static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1749{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001750 struct hci_cp_create_phy_link *cp;
1751
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001752 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001753
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001754 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1755 if (!cp)
1756 return;
1757
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001758 hci_dev_lock(hdev);
1759
1760 if (status) {
1761 struct hci_conn *hcon;
1762
1763 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1764 if (hcon)
1765 hci_conn_del(hcon);
1766 } else {
1767 amp_write_remote_assoc(hdev, cp->phy_handle);
1768 }
1769
1770 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001771}
1772
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001773static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1774{
1775 struct hci_cp_accept_phy_link *cp;
1776
1777 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1778
1779 if (status)
1780 return;
1781
1782 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1783 if (!cp)
1784 return;
1785
1786 amp_write_remote_assoc(hdev, cp->phy_handle);
1787}
1788
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02001789static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
1790{
1791 struct hci_cp_le_create_conn *cp;
1792 struct hci_conn *conn;
1793
1794 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1795
1796 /* All connection failure handling is taken care of by the
1797 * hci_le_conn_failed function which is triggered by the HCI
1798 * request completion callbacks used for connecting.
1799 */
1800 if (status)
1801 return;
1802
1803 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1804 if (!cp)
1805 return;
1806
1807 hci_dev_lock(hdev);
1808
1809 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1810 if (!conn)
1811 goto unlock;
1812
1813 /* Store the initiator and responder address information which
1814 * is needed for SMP. These values will not change during the
1815 * lifetime of the connection.
1816 */
1817 conn->init_addr_type = cp->own_address_type;
1818 if (cp->own_address_type == ADDR_LE_DEV_RANDOM)
1819 bacpy(&conn->init_addr, &hdev->random_addr);
1820 else
1821 bacpy(&conn->init_addr, &hdev->bdaddr);
1822
1823 conn->resp_addr_type = cp->peer_addr_type;
1824 bacpy(&conn->resp_addr, &cp->peer_addr);
1825
Johan Hedberg9489eca2014-02-28 17:45:46 +02001826 /* We don't want the connection attempt to stick around
1827 * indefinitely since LE doesn't have a page timeout concept
1828 * like BR/EDR. Set a timer for any connection that doesn't use
1829 * the white list for connecting.
1830 */
1831 if (cp->filter_policy == HCI_LE_USE_PEER_ADDR)
1832 queue_delayed_work(conn->hdev->workqueue,
1833 &conn->le_conn_timeout,
1834 HCI_LE_CONN_TIMEOUT);
1835
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02001836unlock:
1837 hci_dev_unlock(hdev);
1838}
1839
Johan Hedberg81d0c8a2014-03-24 14:39:04 +02001840static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1841{
1842 struct hci_cp_le_start_enc *cp;
1843 struct hci_conn *conn;
1844
1845 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1846
1847 if (!status)
1848 return;
1849
1850 hci_dev_lock(hdev);
1851
1852 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
1853 if (!cp)
1854 goto unlock;
1855
1856 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1857 if (!conn)
1858 goto unlock;
1859
1860 if (conn->state != BT_CONNECTED)
1861 goto unlock;
1862
1863 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
1864 hci_conn_drop(conn);
1865
1866unlock:
1867 hci_dev_unlock(hdev);
1868}
1869
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001870static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001871{
1872 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001873 struct discovery_state *discov = &hdev->discovery;
1874 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001875
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001876 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001877
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001878 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001879
1880 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1881 return;
1882
Peter Zijlstra4e857c52014-03-17 18:06:10 +01001883 smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
Andre Guedes3e13fa12013-03-27 20:04:56 -03001884 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1885
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001886 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001887 return;
1888
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001889 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001890
Andre Guedes343f9352012-02-17 20:39:37 -03001891 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001892 goto unlock;
1893
1894 if (list_empty(&discov->resolve)) {
1895 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1896 goto unlock;
1897 }
1898
1899 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1900 if (e && hci_resolve_name(hdev, e) == 0) {
1901 e->name_state = NAME_PENDING;
1902 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1903 } else {
1904 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1905 }
1906
1907unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001908 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001909}
1910
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001911static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001913 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001914 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915 int num_rsp = *((__u8 *) skb->data);
1916
1917 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1918
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001919 if (!num_rsp)
1920 return;
1921
Andre Guedes1519cc12012-03-21 00:03:38 -03001922 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1923 return;
1924
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001926
Johan Hedberge17acd42011-03-30 23:57:16 +03001927 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001928 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001929
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930 bacpy(&data.bdaddr, &info->bdaddr);
1931 data.pscan_rep_mode = info->pscan_rep_mode;
1932 data.pscan_period_mode = info->pscan_period_mode;
1933 data.pscan_mode = info->pscan_mode;
1934 memcpy(data.dev_class, info->dev_class, 3);
1935 data.clock_offset = info->clock_offset;
1936 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001937 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001938
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001939 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001940 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001941 info->dev_class, 0, !name_known, ssp, NULL,
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02001942 0, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001944
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945 hci_dev_unlock(hdev);
1946}
1947
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001948static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001950 struct hci_ev_conn_complete *ev = (void *) skb->data;
1951 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001952
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001953 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001954
Linus Torvalds1da177e2005-04-16 15:20:36 -07001955 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001956
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001957 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001958 if (!conn) {
1959 if (ev->link_type != SCO_LINK)
1960 goto unlock;
1961
1962 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1963 if (!conn)
1964 goto unlock;
1965
1966 conn->type = SCO_LINK;
1967 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001968
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001969 if (!ev->status) {
1970 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001971
1972 if (conn->type == ACL_LINK) {
1973 conn->state = BT_CONFIG;
1974 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001975
1976 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1977 !hci_find_link_key(hdev, &ev->bdaddr))
1978 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1979 else
1980 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001981 } else
1982 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001983
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001984 hci_conn_add_sysfs(conn);
1985
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001986 if (test_bit(HCI_AUTH, &hdev->flags))
1987 conn->link_mode |= HCI_LM_AUTH;
1988
1989 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1990 conn->link_mode |= HCI_LM_ENCRYPT;
1991
1992 /* Get remote features */
1993 if (conn->type == ACL_LINK) {
1994 struct hci_cp_read_remote_features cp;
1995 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001996 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001997 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001998 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001999
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002000 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02002001 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002002 struct hci_cp_change_conn_ptype cp;
2003 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02002004 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002005 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
2006 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002007 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02002008 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002009 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02002010 if (conn->type == ACL_LINK)
Marcel Holtmann64c7b772014-02-18 14:22:20 -08002011 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002012 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02002013 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002014
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002015 if (conn->type == ACL_LINK)
2016 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07002017
Marcel Holtmann769be972008-07-14 20:13:49 +02002018 if (ev->status) {
2019 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002020 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01002021 } else if (ev->link_type != ACL_LINK)
2022 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002023
2024unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002025 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002026
2027 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028}
2029
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002030static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002032 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002033 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002034 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002035
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002036 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002037 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002039 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
2040 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041
Szymon Janc138d22e2011-02-17 16:44:23 +01002042 if ((mask & HCI_LM_ACCEPT) &&
Marcel Holtmannb9ee0a72013-10-17 17:24:13 -07002043 !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002044 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02002045 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047
2048 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002049
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002050 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2051 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02002052 memcpy(ie->data.dev_class, ev->dev_class, 3);
2053
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002054 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
2055 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002056 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002057 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
2058 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03002059 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002060 hci_dev_unlock(hdev);
2061 return;
2062 }
2063 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002064
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002066
Linus Torvalds1da177e2005-04-16 15:20:36 -07002067 hci_dev_unlock(hdev);
2068
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002069 if (ev->link_type == ACL_LINK ||
2070 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002071 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002072 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002074 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002075
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002076 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
2077 cp.role = 0x00; /* Become master */
2078 else
2079 cp.role = 0x01; /* Remain slave */
2080
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002081 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
2082 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002083 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002084 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002085 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002086
2087 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002088 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002089
Joe Perchesdcf4adb2014-03-12 10:52:35 -07002090 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
2091 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
2092 cp.max_latency = cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002093 cp.content_format = cpu_to_le16(hdev->voice_setting);
2094 cp.retrans_effort = 0xff;
2095
2096 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002097 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002098 } else {
2099 conn->state = BT_CONNECT2;
2100 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002101 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002102 } else {
2103 /* Connection rejected */
2104 struct hci_cp_reject_conn_req cp;
2105
2106 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002107 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002108 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109 }
2110}
2111
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02002112static u8 hci_to_mgmt_reason(u8 err)
2113{
2114 switch (err) {
2115 case HCI_ERROR_CONNECTION_TIMEOUT:
2116 return MGMT_DEV_DISCONN_TIMEOUT;
2117 case HCI_ERROR_REMOTE_USER_TERM:
2118 case HCI_ERROR_REMOTE_LOW_RESOURCES:
2119 case HCI_ERROR_REMOTE_POWER_OFF:
2120 return MGMT_DEV_DISCONN_REMOTE;
2121 case HCI_ERROR_LOCAL_HOST_TERM:
2122 return MGMT_DEV_DISCONN_LOCAL_HOST;
2123 default:
2124 return MGMT_DEV_DISCONN_UNKNOWN;
2125 }
2126}
2127
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002128static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002130 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Andre Guedesabf54a52013-11-07 17:36:09 -03002131 u8 reason = hci_to_mgmt_reason(ev->reason);
Andre Guedes9fcb18e2014-02-26 20:21:48 -03002132 struct hci_conn_params *params;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002133 struct hci_conn *conn;
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02002134 bool mgmt_connected;
Andre Guedes38462202013-11-07 17:36:10 -03002135 u8 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002136
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002137 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002138
Linus Torvalds1da177e2005-04-16 15:20:36 -07002139 hci_dev_lock(hdev);
2140
Marcel Holtmann04837f62006-07-03 10:02:33 +02002141 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02002142 if (!conn)
2143 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002144
Andre Guedesabf54a52013-11-07 17:36:09 -03002145 if (ev->status) {
2146 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
2147 conn->dst_type, ev->status);
2148 goto unlock;
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002149 }
Johan Hedbergf7520542011-01-20 12:34:39 +02002150
Andre Guedes38462202013-11-07 17:36:10 -03002151 conn->state = BT_CLOSED;
2152
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02002153 mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
2154 mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
2155 reason, mgmt_connected);
Andre Guedesabf54a52013-11-07 17:36:09 -03002156
Andre Guedes38462202013-11-07 17:36:10 -03002157 if (conn->type == ACL_LINK && conn->flush_key)
2158 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg22102462013-10-05 12:01:06 +02002159
Andre Guedes9fcb18e2014-02-26 20:21:48 -03002160 params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
2161 if (params) {
2162 switch (params->auto_connect) {
2163 case HCI_AUTO_CONN_LINK_LOSS:
2164 if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
2165 break;
2166 /* Fall through */
2167
2168 case HCI_AUTO_CONN_ALWAYS:
2169 hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type);
2170 break;
2171
2172 default:
2173 break;
2174 }
2175 }
2176
Andre Guedes38462202013-11-07 17:36:10 -03002177 type = conn->type;
Johan Hedberg22102462013-10-05 12:01:06 +02002178
Andre Guedes38462202013-11-07 17:36:10 -03002179 hci_proto_disconn_cfm(conn, ev->reason);
2180 hci_conn_del(conn);
2181
2182 /* Re-enable advertising if necessary, since it might
2183 * have been disabled by the connection. From the
2184 * HCI_LE_Set_Advertise_Enable command description in
2185 * the core specification (v4.0):
2186 * "The Controller shall continue advertising until the Host
2187 * issues an LE_Set_Advertise_Enable command with
2188 * Advertising_Enable set to 0x00 (Advertising is disabled)
2189 * or until a connection is created or until the Advertising
2190 * is timed out due to Directed Advertising."
2191 */
2192 if (type == LE_LINK)
2193 mgmt_reenable_advertising(hdev);
Johan Hedbergf7520542011-01-20 12:34:39 +02002194
2195unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002196 hci_dev_unlock(hdev);
2197}
2198
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002199static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002200{
2201 struct hci_ev_auth_complete *ev = (void *) skb->data;
2202 struct hci_conn *conn;
2203
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002204 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002205
2206 hci_dev_lock(hdev);
2207
2208 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002209 if (!conn)
2210 goto unlock;
2211
2212 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002213 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002214 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002215 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03002216 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002217 conn->link_mode |= HCI_LM_AUTH;
2218 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03002219 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002220 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02002221 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002222 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002223 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002224
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002225 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
2226 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002227
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002228 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002229 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002230 struct hci_cp_set_conn_encrypt cp;
2231 cp.handle = ev->handle;
2232 cp.encrypt = 0x01;
2233 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002234 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002235 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002236 conn->state = BT_CONNECTED;
2237 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002238 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002239 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002240 } else {
2241 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002242
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002243 hci_conn_hold(conn);
2244 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002245 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002246 }
2247
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002248 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002249 if (!ev->status) {
2250 struct hci_cp_set_conn_encrypt cp;
2251 cp.handle = ev->handle;
2252 cp.encrypt = 0x01;
2253 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002254 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002255 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002256 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002257 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002258 }
2259 }
2260
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002261unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002262 hci_dev_unlock(hdev);
2263}
2264
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002265static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002266{
Johan Hedberg127178d2010-11-18 22:22:29 +02002267 struct hci_ev_remote_name *ev = (void *) skb->data;
2268 struct hci_conn *conn;
2269
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002270 BT_DBG("%s", hdev->name);
2271
2272 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02002273
2274 hci_dev_lock(hdev);
2275
2276 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002277
2278 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2279 goto check_auth;
2280
2281 if (ev->status == 0)
2282 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002283 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002284 else
2285 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2286
2287check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002288 if (!conn)
2289 goto unlock;
2290
2291 if (!hci_outgoing_auth_needed(hdev, conn))
2292 goto unlock;
2293
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002294 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002295 struct hci_cp_auth_requested cp;
2296 cp.handle = __cpu_to_le16(conn->handle);
2297 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2298 }
2299
Johan Hedberg79c6c702011-04-28 11:28:55 -07002300unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002301 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002302}
2303
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002304static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002305{
2306 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2307 struct hci_conn *conn;
2308
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002309 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002310
2311 hci_dev_lock(hdev);
2312
2313 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002314 if (!conn)
2315 goto unlock;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002316
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002317 if (!ev->status) {
2318 if (ev->encrypt) {
2319 /* Encryption implies authentication */
2320 conn->link_mode |= HCI_LM_AUTH;
2321 conn->link_mode |= HCI_LM_ENCRYPT;
2322 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002323
Marcel Holtmann914a6ff2014-02-01 11:52:02 -08002324 /* P-256 authentication key implies FIPS */
2325 if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
2326 conn->link_mode |= HCI_LM_FIPS;
2327
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002328 if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
2329 conn->type == LE_LINK)
2330 set_bit(HCI_CONN_AES_CCM, &conn->flags);
2331 } else {
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002332 conn->link_mode &= ~HCI_LM_ENCRYPT;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002333 clear_bit(HCI_CONN_AES_CCM, &conn->flags);
2334 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002335 }
2336
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002337 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2338
2339 if (ev->status && conn->state == BT_CONNECTED) {
2340 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
2341 hci_conn_drop(conn);
2342 goto unlock;
2343 }
2344
2345 if (conn->state == BT_CONFIG) {
2346 if (!ev->status)
2347 conn->state = BT_CONNECTED;
2348
Marcel Holtmann40b552a2014-03-19 14:10:25 -07002349 /* In Secure Connections Only mode, do not allow any
2350 * connections that are not encrypted with AES-CCM
2351 * using a P-256 authenticated combination key.
2352 */
2353 if (test_bit(HCI_SC_ONLY, &hdev->dev_flags) &&
2354 (!test_bit(HCI_CONN_AES_CCM, &conn->flags) ||
2355 conn->key_type != HCI_LK_AUTH_COMBINATION_P256)) {
2356 hci_proto_connect_cfm(conn, HCI_ERROR_AUTH_FAILURE);
2357 hci_conn_drop(conn);
2358 goto unlock;
2359 }
2360
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002361 hci_proto_connect_cfm(conn, ev->status);
2362 hci_conn_drop(conn);
2363 } else
2364 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
2365
Gustavo Padovana7d77232012-05-13 03:20:07 -03002366unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002367 hci_dev_unlock(hdev);
2368}
2369
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002370static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2371 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002372{
2373 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2374 struct hci_conn *conn;
2375
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002376 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002377
2378 hci_dev_lock(hdev);
2379
2380 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2381 if (conn) {
2382 if (!ev->status)
2383 conn->link_mode |= HCI_LM_SECURE;
2384
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002385 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002386
2387 hci_key_change_cfm(conn, ev->status);
2388 }
2389
2390 hci_dev_unlock(hdev);
2391}
2392
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002393static void hci_remote_features_evt(struct hci_dev *hdev,
2394 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002395{
2396 struct hci_ev_remote_features *ev = (void *) skb->data;
2397 struct hci_conn *conn;
2398
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002399 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002400
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002401 hci_dev_lock(hdev);
2402
2403 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002404 if (!conn)
2405 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002406
Johan Hedbergccd556f2010-11-10 17:11:51 +02002407 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002408 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002409
2410 if (conn->state != BT_CONFIG)
2411 goto unlock;
2412
2413 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2414 struct hci_cp_read_remote_ext_features cp;
2415 cp.handle = ev->handle;
2416 cp.page = 0x01;
2417 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002418 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002419 goto unlock;
2420 }
2421
Johan Hedberg671267b2012-05-12 16:11:50 -03002422 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002423 struct hci_cp_remote_name_req cp;
2424 memset(&cp, 0, sizeof(cp));
2425 bacpy(&cp.bdaddr, &conn->dst);
2426 cp.pscan_rep_mode = 0x02;
2427 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002428 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2429 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002430 conn->dst_type, 0, NULL, 0,
2431 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002432
Johan Hedberg127178d2010-11-18 22:22:29 +02002433 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002434 conn->state = BT_CONNECTED;
2435 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002436 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002437 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002438
Johan Hedbergccd556f2010-11-10 17:11:51 +02002439unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002440 hci_dev_unlock(hdev);
2441}
2442
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002443static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002444{
2445 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002446 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002447 __u16 opcode;
2448
2449 skb_pull(skb, sizeof(*ev));
2450
2451 opcode = __le16_to_cpu(ev->opcode);
2452
2453 switch (opcode) {
2454 case HCI_OP_INQUIRY_CANCEL:
2455 hci_cc_inquiry_cancel(hdev, skb);
2456 break;
2457
Andre Guedes4d934832012-03-21 00:03:35 -03002458 case HCI_OP_PERIODIC_INQ:
2459 hci_cc_periodic_inq(hdev, skb);
2460 break;
2461
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002462 case HCI_OP_EXIT_PERIODIC_INQ:
2463 hci_cc_exit_periodic_inq(hdev, skb);
2464 break;
2465
2466 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2467 hci_cc_remote_name_req_cancel(hdev, skb);
2468 break;
2469
2470 case HCI_OP_ROLE_DISCOVERY:
2471 hci_cc_role_discovery(hdev, skb);
2472 break;
2473
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002474 case HCI_OP_READ_LINK_POLICY:
2475 hci_cc_read_link_policy(hdev, skb);
2476 break;
2477
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002478 case HCI_OP_WRITE_LINK_POLICY:
2479 hci_cc_write_link_policy(hdev, skb);
2480 break;
2481
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002482 case HCI_OP_READ_DEF_LINK_POLICY:
2483 hci_cc_read_def_link_policy(hdev, skb);
2484 break;
2485
2486 case HCI_OP_WRITE_DEF_LINK_POLICY:
2487 hci_cc_write_def_link_policy(hdev, skb);
2488 break;
2489
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002490 case HCI_OP_RESET:
2491 hci_cc_reset(hdev, skb);
2492 break;
2493
2494 case HCI_OP_WRITE_LOCAL_NAME:
2495 hci_cc_write_local_name(hdev, skb);
2496 break;
2497
2498 case HCI_OP_READ_LOCAL_NAME:
2499 hci_cc_read_local_name(hdev, skb);
2500 break;
2501
2502 case HCI_OP_WRITE_AUTH_ENABLE:
2503 hci_cc_write_auth_enable(hdev, skb);
2504 break;
2505
2506 case HCI_OP_WRITE_ENCRYPT_MODE:
2507 hci_cc_write_encrypt_mode(hdev, skb);
2508 break;
2509
2510 case HCI_OP_WRITE_SCAN_ENABLE:
2511 hci_cc_write_scan_enable(hdev, skb);
2512 break;
2513
2514 case HCI_OP_READ_CLASS_OF_DEV:
2515 hci_cc_read_class_of_dev(hdev, skb);
2516 break;
2517
2518 case HCI_OP_WRITE_CLASS_OF_DEV:
2519 hci_cc_write_class_of_dev(hdev, skb);
2520 break;
2521
2522 case HCI_OP_READ_VOICE_SETTING:
2523 hci_cc_read_voice_setting(hdev, skb);
2524 break;
2525
2526 case HCI_OP_WRITE_VOICE_SETTING:
2527 hci_cc_write_voice_setting(hdev, skb);
2528 break;
2529
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002530 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2531 hci_cc_read_num_supported_iac(hdev, skb);
2532 break;
2533
Marcel Holtmann333140b2008-07-14 20:13:48 +02002534 case HCI_OP_WRITE_SSP_MODE:
2535 hci_cc_write_ssp_mode(hdev, skb);
2536 break;
2537
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08002538 case HCI_OP_WRITE_SC_SUPPORT:
2539 hci_cc_write_sc_support(hdev, skb);
2540 break;
2541
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002542 case HCI_OP_READ_LOCAL_VERSION:
2543 hci_cc_read_local_version(hdev, skb);
2544 break;
2545
2546 case HCI_OP_READ_LOCAL_COMMANDS:
2547 hci_cc_read_local_commands(hdev, skb);
2548 break;
2549
2550 case HCI_OP_READ_LOCAL_FEATURES:
2551 hci_cc_read_local_features(hdev, skb);
2552 break;
2553
Andre Guedes971e3a42011-06-30 19:20:52 -03002554 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2555 hci_cc_read_local_ext_features(hdev, skb);
2556 break;
2557
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002558 case HCI_OP_READ_BUFFER_SIZE:
2559 hci_cc_read_buffer_size(hdev, skb);
2560 break;
2561
2562 case HCI_OP_READ_BD_ADDR:
2563 hci_cc_read_bd_addr(hdev, skb);
2564 break;
2565
Johan Hedbergf332ec62013-03-15 17:07:11 -05002566 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2567 hci_cc_read_page_scan_activity(hdev, skb);
2568 break;
2569
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002570 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2571 hci_cc_write_page_scan_activity(hdev, skb);
2572 break;
2573
Johan Hedbergf332ec62013-03-15 17:07:11 -05002574 case HCI_OP_READ_PAGE_SCAN_TYPE:
2575 hci_cc_read_page_scan_type(hdev, skb);
2576 break;
2577
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002578 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2579 hci_cc_write_page_scan_type(hdev, skb);
2580 break;
2581
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002582 case HCI_OP_READ_DATA_BLOCK_SIZE:
2583 hci_cc_read_data_block_size(hdev, skb);
2584 break;
2585
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002586 case HCI_OP_READ_FLOW_CONTROL_MODE:
2587 hci_cc_read_flow_control_mode(hdev, skb);
2588 break;
2589
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002590 case HCI_OP_READ_LOCAL_AMP_INFO:
2591 hci_cc_read_local_amp_info(hdev, skb);
2592 break;
2593
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002594 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2595 hci_cc_read_local_amp_assoc(hdev, skb);
2596 break;
2597
Johan Hedbergd5859e22011-01-25 01:19:58 +02002598 case HCI_OP_READ_INQ_RSP_TX_POWER:
2599 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2600 break;
2601
Johan Hedberg980e1a52011-01-22 06:10:07 +02002602 case HCI_OP_PIN_CODE_REPLY:
2603 hci_cc_pin_code_reply(hdev, skb);
2604 break;
2605
2606 case HCI_OP_PIN_CODE_NEG_REPLY:
2607 hci_cc_pin_code_neg_reply(hdev, skb);
2608 break;
2609
Szymon Jancc35938b2011-03-22 13:12:21 +01002610 case HCI_OP_READ_LOCAL_OOB_DATA:
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08002611 hci_cc_read_local_oob_data(hdev, skb);
2612 break;
2613
2614 case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
2615 hci_cc_read_local_oob_ext_data(hdev, skb);
Szymon Jancc35938b2011-03-22 13:12:21 +01002616 break;
2617
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002618 case HCI_OP_LE_READ_BUFFER_SIZE:
2619 hci_cc_le_read_buffer_size(hdev, skb);
2620 break;
2621
Johan Hedberg60e77322013-01-22 14:01:59 +02002622 case HCI_OP_LE_READ_LOCAL_FEATURES:
2623 hci_cc_le_read_local_features(hdev, skb);
2624 break;
2625
Johan Hedberg8fa19092012-10-19 20:57:49 +03002626 case HCI_OP_LE_READ_ADV_TX_POWER:
2627 hci_cc_le_read_adv_tx_power(hdev, skb);
2628 break;
2629
Johan Hedberga5c29682011-02-19 12:05:57 -03002630 case HCI_OP_USER_CONFIRM_REPLY:
2631 hci_cc_user_confirm_reply(hdev, skb);
2632 break;
2633
2634 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2635 hci_cc_user_confirm_neg_reply(hdev, skb);
2636 break;
2637
Brian Gix1143d452011-11-23 08:28:34 -08002638 case HCI_OP_USER_PASSKEY_REPLY:
2639 hci_cc_user_passkey_reply(hdev, skb);
2640 break;
2641
2642 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2643 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002644 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002645
Marcel Holtmann7a4cd512014-02-19 19:52:13 -08002646 case HCI_OP_LE_SET_RANDOM_ADDR:
2647 hci_cc_le_set_random_addr(hdev, skb);
2648 break;
2649
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002650 case HCI_OP_LE_SET_ADV_ENABLE:
2651 hci_cc_le_set_adv_enable(hdev, skb);
2652 break;
2653
Marcel Holtmann533553f2014-03-21 12:18:10 -07002654 case HCI_OP_LE_SET_SCAN_PARAM:
2655 hci_cc_le_set_scan_param(hdev, skb);
2656 break;
2657
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002658 case HCI_OP_LE_SET_SCAN_ENABLE:
2659 hci_cc_le_set_scan_enable(hdev, skb);
2660 break;
2661
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002662 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2663 hci_cc_le_read_white_list_size(hdev, skb);
2664 break;
2665
Marcel Holtmann0f36b582014-02-27 20:37:31 -08002666 case HCI_OP_LE_CLEAR_WHITE_LIST:
2667 hci_cc_le_clear_white_list(hdev, skb);
2668 break;
2669
2670 case HCI_OP_LE_ADD_TO_WHITE_LIST:
2671 hci_cc_le_add_to_white_list(hdev, skb);
2672 break;
2673
2674 case HCI_OP_LE_DEL_FROM_WHITE_LIST:
2675 hci_cc_le_del_from_white_list(hdev, skb);
2676 break;
2677
Johan Hedberg9b008c02013-01-22 14:02:01 +02002678 case HCI_OP_LE_READ_SUPPORTED_STATES:
2679 hci_cc_le_read_supported_states(hdev, skb);
2680 break;
2681
Andre Guedesf9b49302011-06-30 19:20:53 -03002682 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2683 hci_cc_write_le_host_supported(hdev, skb);
2684 break;
2685
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02002686 case HCI_OP_LE_SET_ADV_PARAM:
2687 hci_cc_set_adv_param(hdev, skb);
2688 break;
2689
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002690 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2691 hci_cc_write_remote_amp_assoc(hdev, skb);
2692 break;
2693
Andrzej Kaczmarek5ae76a92014-05-08 15:32:08 +02002694 case HCI_OP_READ_RSSI:
2695 hci_cc_read_rssi(hdev, skb);
2696 break;
2697
Andrzej Kaczmarek5a134fa2014-05-09 21:35:28 +02002698 case HCI_OP_READ_TX_POWER:
2699 hci_cc_read_tx_power(hdev, skb);
2700 break;
2701
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002702 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002703 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002704 break;
2705 }
2706
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002707 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002708 del_timer(&hdev->cmd_timer);
2709
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002710 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002711
Szymon Jancdbccd792012-12-11 08:51:19 +01002712 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002713 atomic_set(&hdev->cmd_cnt, 1);
2714 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002715 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002716 }
2717}
2718
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002719static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002720{
2721 struct hci_ev_cmd_status *ev = (void *) skb->data;
2722 __u16 opcode;
2723
2724 skb_pull(skb, sizeof(*ev));
2725
2726 opcode = __le16_to_cpu(ev->opcode);
2727
2728 switch (opcode) {
2729 case HCI_OP_INQUIRY:
2730 hci_cs_inquiry(hdev, ev->status);
2731 break;
2732
2733 case HCI_OP_CREATE_CONN:
2734 hci_cs_create_conn(hdev, ev->status);
2735 break;
2736
2737 case HCI_OP_ADD_SCO:
2738 hci_cs_add_sco(hdev, ev->status);
2739 break;
2740
Marcel Holtmannf8558552008-07-14 20:13:49 +02002741 case HCI_OP_AUTH_REQUESTED:
2742 hci_cs_auth_requested(hdev, ev->status);
2743 break;
2744
2745 case HCI_OP_SET_CONN_ENCRYPT:
2746 hci_cs_set_conn_encrypt(hdev, ev->status);
2747 break;
2748
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002749 case HCI_OP_REMOTE_NAME_REQ:
2750 hci_cs_remote_name_req(hdev, ev->status);
2751 break;
2752
Marcel Holtmann769be972008-07-14 20:13:49 +02002753 case HCI_OP_READ_REMOTE_FEATURES:
2754 hci_cs_read_remote_features(hdev, ev->status);
2755 break;
2756
2757 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2758 hci_cs_read_remote_ext_features(hdev, ev->status);
2759 break;
2760
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002761 case HCI_OP_SETUP_SYNC_CONN:
2762 hci_cs_setup_sync_conn(hdev, ev->status);
2763 break;
2764
2765 case HCI_OP_SNIFF_MODE:
2766 hci_cs_sniff_mode(hdev, ev->status);
2767 break;
2768
2769 case HCI_OP_EXIT_SNIFF_MODE:
2770 hci_cs_exit_sniff_mode(hdev, ev->status);
2771 break;
2772
Johan Hedberg8962ee72011-01-20 12:40:27 +02002773 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002774 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002775 break;
2776
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002777 case HCI_OP_CREATE_PHY_LINK:
2778 hci_cs_create_phylink(hdev, ev->status);
2779 break;
2780
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002781 case HCI_OP_ACCEPT_PHY_LINK:
2782 hci_cs_accept_phylink(hdev, ev->status);
2783 break;
2784
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02002785 case HCI_OP_LE_CREATE_CONN:
2786 hci_cs_le_create_conn(hdev, ev->status);
2787 break;
2788
Johan Hedberg81d0c8a2014-03-24 14:39:04 +02002789 case HCI_OP_LE_START_ENC:
2790 hci_cs_le_start_enc(hdev, ev->status);
2791 break;
2792
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002793 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002794 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002795 break;
2796 }
2797
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002798 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002799 del_timer(&hdev->cmd_timer);
2800
Johan Hedberg02350a72013-04-03 21:50:29 +03002801 if (ev->status ||
2802 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2803 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002804
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002805 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002806 atomic_set(&hdev->cmd_cnt, 1);
2807 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002808 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002809 }
2810}
2811
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002812static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002813{
2814 struct hci_ev_role_change *ev = (void *) skb->data;
2815 struct hci_conn *conn;
2816
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002817 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002818
2819 hci_dev_lock(hdev);
2820
2821 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2822 if (conn) {
2823 if (!ev->status) {
2824 if (ev->role)
2825 conn->link_mode &= ~HCI_LM_MASTER;
2826 else
2827 conn->link_mode |= HCI_LM_MASTER;
2828 }
2829
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002830 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002831
2832 hci_role_switch_cfm(conn, ev->status, ev->role);
2833 }
2834
2835 hci_dev_unlock(hdev);
2836}
2837
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002838static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002839{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002840 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002841 int i;
2842
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002843 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2844 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2845 return;
2846 }
2847
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002848 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002849 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850 BT_DBG("%s bad parameters", hdev->name);
2851 return;
2852 }
2853
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002854 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2855
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002856 for (i = 0; i < ev->num_hndl; i++) {
2857 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858 struct hci_conn *conn;
2859 __u16 handle, count;
2860
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002861 handle = __le16_to_cpu(info->handle);
2862 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002863
2864 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002865 if (!conn)
2866 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002868 conn->sent -= count;
2869
2870 switch (conn->type) {
2871 case ACL_LINK:
2872 hdev->acl_cnt += count;
2873 if (hdev->acl_cnt > hdev->acl_pkts)
2874 hdev->acl_cnt = hdev->acl_pkts;
2875 break;
2876
2877 case LE_LINK:
2878 if (hdev->le_pkts) {
2879 hdev->le_cnt += count;
2880 if (hdev->le_cnt > hdev->le_pkts)
2881 hdev->le_cnt = hdev->le_pkts;
2882 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002883 hdev->acl_cnt += count;
2884 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002885 hdev->acl_cnt = hdev->acl_pkts;
2886 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002887 break;
2888
2889 case SCO_LINK:
2890 hdev->sco_cnt += count;
2891 if (hdev->sco_cnt > hdev->sco_pkts)
2892 hdev->sco_cnt = hdev->sco_pkts;
2893 break;
2894
2895 default:
2896 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2897 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002898 }
2899 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002900
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002901 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002902}
2903
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002904static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2905 __u16 handle)
2906{
2907 struct hci_chan *chan;
2908
2909 switch (hdev->dev_type) {
2910 case HCI_BREDR:
2911 return hci_conn_hash_lookup_handle(hdev, handle);
2912 case HCI_AMP:
2913 chan = hci_chan_lookup_handle(hdev, handle);
2914 if (chan)
2915 return chan->conn;
2916 break;
2917 default:
2918 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2919 break;
2920 }
2921
2922 return NULL;
2923}
2924
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002925static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002926{
2927 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2928 int i;
2929
2930 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2931 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2932 return;
2933 }
2934
2935 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002936 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002937 BT_DBG("%s bad parameters", hdev->name);
2938 return;
2939 }
2940
2941 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002942 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002943
2944 for (i = 0; i < ev->num_hndl; i++) {
2945 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002946 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002947 __u16 handle, block_count;
2948
2949 handle = __le16_to_cpu(info->handle);
2950 block_count = __le16_to_cpu(info->blocks);
2951
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002952 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002953 if (!conn)
2954 continue;
2955
2956 conn->sent -= block_count;
2957
2958 switch (conn->type) {
2959 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002960 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002961 hdev->block_cnt += block_count;
2962 if (hdev->block_cnt > hdev->num_blocks)
2963 hdev->block_cnt = hdev->num_blocks;
2964 break;
2965
2966 default:
2967 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2968 break;
2969 }
2970 }
2971
2972 queue_work(hdev->workqueue, &hdev->tx_work);
2973}
2974
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002975static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002976{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002977 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002978 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002980 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002981
2982 hci_dev_lock(hdev);
2983
Marcel Holtmann04837f62006-07-03 10:02:33 +02002984 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2985 if (conn) {
2986 conn->mode = ev->mode;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002987
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002988 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2989 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002990 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002991 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002992 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002993 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002994 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002995
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002996 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002997 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002998 }
2999
3000 hci_dev_unlock(hdev);
3001}
3002
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003003static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003005 struct hci_ev_pin_code_req *ev = (void *) skb->data;
3006 struct hci_conn *conn;
3007
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003008 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003009
3010 hci_dev_lock(hdev);
3011
3012 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02003013 if (!conn)
3014 goto unlock;
3015
3016 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003017 hci_conn_hold(conn);
3018 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003019 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003020 }
3021
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003022 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003023 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003024 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003025 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02003026 u8 secure;
3027
3028 if (conn->pending_sec_level == BT_SECURITY_HIGH)
3029 secure = 1;
3030 else
3031 secure = 0;
3032
Johan Hedberg744cf192011-11-08 20:40:14 +02003033 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02003034 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02003035
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02003036unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003037 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003038}
3039
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003040static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003041{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003042 struct hci_ev_link_key_req *ev = (void *) skb->data;
3043 struct hci_cp_link_key_reply cp;
3044 struct hci_conn *conn;
3045 struct link_key *key;
3046
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003047 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003048
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03003049 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003050 return;
3051
3052 hci_dev_lock(hdev);
3053
3054 key = hci_find_link_key(hdev, &ev->bdaddr);
3055 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03003056 BT_DBG("%s link key not found for %pMR", hdev->name,
3057 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003058 goto not_found;
3059 }
3060
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03003061 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
3062 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003063
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003064 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003065 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003066 BT_DBG("%s ignoring debug key", hdev->name);
3067 goto not_found;
3068 }
3069
3070 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02003071 if (conn) {
Marcel Holtmann66138ce2014-01-10 02:07:20 -08003072 if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
3073 key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003074 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02003075 BT_DBG("%s ignoring unauthenticated key", hdev->name);
3076 goto not_found;
3077 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003078
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02003079 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Johan Hedbergf3fb0b52014-06-02 10:12:44 +03003080 (conn->pending_sec_level == BT_SECURITY_HIGH ||
3081 conn->pending_sec_level == BT_SECURITY_FIPS)) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003082 BT_DBG("%s ignoring key unauthenticated for high security",
3083 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02003084 goto not_found;
3085 }
3086
3087 conn->key_type = key->type;
3088 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003089 }
3090
3091 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03003092 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003093
3094 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
3095
3096 hci_dev_unlock(hdev);
3097
3098 return;
3099
3100not_found:
3101 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
3102 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003103}
3104
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003105static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003106{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003107 struct hci_ev_link_key_notify *ev = (void *) skb->data;
3108 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003109 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003110
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003111 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003112
3113 hci_dev_lock(hdev);
3114
3115 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3116 if (conn) {
3117 hci_conn_hold(conn);
3118 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02003119 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02003120
3121 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
3122 conn->key_type = ev->key_type;
3123
David Herrmann76a68ba2013-04-06 20:28:37 +02003124 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003125 }
3126
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03003127 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07003128 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003129 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003130
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003131 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003132}
3133
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003134static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02003135{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003136 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02003137 struct hci_conn *conn;
3138
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003139 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02003140
3141 hci_dev_lock(hdev);
3142
3143 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003144 if (conn && !ev->status) {
3145 struct inquiry_entry *ie;
3146
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003147 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3148 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003149 ie->data.clock_offset = ev->clock_offset;
3150 ie->timestamp = jiffies;
3151 }
3152 }
3153
3154 hci_dev_unlock(hdev);
3155}
3156
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003157static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02003158{
3159 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
3160 struct hci_conn *conn;
3161
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003162 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02003163
3164 hci_dev_lock(hdev);
3165
3166 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3167 if (conn && !ev->status)
3168 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
3169
3170 hci_dev_unlock(hdev);
3171}
3172
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003173static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003174{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003175 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003176 struct inquiry_entry *ie;
3177
3178 BT_DBG("%s", hdev->name);
3179
3180 hci_dev_lock(hdev);
3181
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003182 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3183 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003184 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
3185 ie->timestamp = jiffies;
3186 }
3187
3188 hci_dev_unlock(hdev);
3189}
3190
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003191static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
3192 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003193{
3194 struct inquiry_data data;
3195 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003196 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003197
3198 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3199
3200 if (!num_rsp)
3201 return;
3202
Andre Guedes1519cc12012-03-21 00:03:38 -03003203 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3204 return;
3205
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003206 hci_dev_lock(hdev);
3207
3208 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01003209 struct inquiry_info_with_rssi_and_pscan_mode *info;
3210 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003211
Johan Hedberge17acd42011-03-30 23:57:16 +03003212 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003213 bacpy(&data.bdaddr, &info->bdaddr);
3214 data.pscan_rep_mode = info->pscan_rep_mode;
3215 data.pscan_period_mode = info->pscan_period_mode;
3216 data.pscan_mode = info->pscan_mode;
3217 memcpy(data.dev_class, info->dev_class, 3);
3218 data.clock_offset = info->clock_offset;
3219 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003220 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003221
3222 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003223 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003224 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003225 info->dev_class, info->rssi,
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02003226 !name_known, ssp, NULL, 0, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003227 }
3228 } else {
3229 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
3230
Johan Hedberge17acd42011-03-30 23:57:16 +03003231 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003232 bacpy(&data.bdaddr, &info->bdaddr);
3233 data.pscan_rep_mode = info->pscan_rep_mode;
3234 data.pscan_period_mode = info->pscan_period_mode;
3235 data.pscan_mode = 0x00;
3236 memcpy(data.dev_class, info->dev_class, 3);
3237 data.clock_offset = info->clock_offset;
3238 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003239 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003240 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003241 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003242 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003243 info->dev_class, info->rssi,
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02003244 !name_known, ssp, NULL, 0, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003245 }
3246 }
3247
3248 hci_dev_unlock(hdev);
3249}
3250
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003251static void hci_remote_ext_features_evt(struct hci_dev *hdev,
3252 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003253{
Marcel Holtmann41a96212008-07-14 20:13:48 +02003254 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
3255 struct hci_conn *conn;
3256
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003257 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003258
Marcel Holtmann41a96212008-07-14 20:13:48 +02003259 hci_dev_lock(hdev);
3260
3261 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02003262 if (!conn)
3263 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003264
Johan Hedbergcad718e2013-04-17 15:00:51 +03003265 if (ev->page < HCI_MAX_PAGES)
3266 memcpy(conn->features[ev->page], ev->features, 8);
3267
Johan Hedbergccd556f2010-11-10 17:11:51 +02003268 if (!ev->status && ev->page == 0x01) {
3269 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003270
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003271 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3272 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003273 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02003274
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05303275 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02003276 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05303277 } else {
3278 /* It is mandatory by the Bluetooth specification that
3279 * Extended Inquiry Results are only used when Secure
3280 * Simple Pairing is enabled, but some devices violate
3281 * this.
3282 *
3283 * To make these devices work, the internal SSP
3284 * enabled flag needs to be cleared if the remote host
3285 * features do not indicate SSP support */
3286 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
3287 }
Marcel Holtmanneb9a8f32014-01-15 22:37:38 -08003288
3289 if (ev->features[0] & LMP_HOST_SC)
3290 set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003291 }
3292
Johan Hedbergccd556f2010-11-10 17:11:51 +02003293 if (conn->state != BT_CONFIG)
3294 goto unlock;
3295
Johan Hedberg671267b2012-05-12 16:11:50 -03003296 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02003297 struct hci_cp_remote_name_req cp;
3298 memset(&cp, 0, sizeof(cp));
3299 bacpy(&cp.bdaddr, &conn->dst);
3300 cp.pscan_rep_mode = 0x02;
3301 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02003302 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3303 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003304 conn->dst_type, 0, NULL, 0,
3305 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02003306
Johan Hedberg127178d2010-11-18 22:22:29 +02003307 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02003308 conn->state = BT_CONNECTED;
3309 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003310 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02003311 }
3312
3313unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02003314 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003315}
3316
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003317static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
3318 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003319{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003320 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
3321 struct hci_conn *conn;
3322
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003323 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003324
3325 hci_dev_lock(hdev);
3326
3327 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02003328 if (!conn) {
3329 if (ev->link_type == ESCO_LINK)
3330 goto unlock;
3331
3332 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
3333 if (!conn)
3334 goto unlock;
3335
3336 conn->type = SCO_LINK;
3337 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003338
Marcel Holtmann732547f2009-04-19 19:14:14 +02003339 switch (ev->status) {
3340 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003341 conn->handle = __le16_to_cpu(ev->handle);
3342 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02003343
3344 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02003345 break;
3346
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02003347 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05003348 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003349 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08003350 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003351 case 0x1f: /* Unspecified error */
Andrew Earl27539bc2014-03-10 10:31:04 +00003352 case 0x20: /* Unsupported LMP Parameter value */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003353 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02003354 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
3355 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003356 if (hci_setup_sync(conn, conn->link->handle))
3357 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003358 }
3359 /* fall through */
3360
3361 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003362 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003363 break;
3364 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003365
3366 hci_proto_connect_cfm(conn, ev->status);
3367 if (ev->status)
3368 hci_conn_del(conn);
3369
3370unlock:
3371 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003372}
3373
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07003374static inline size_t eir_get_length(u8 *eir, size_t eir_len)
3375{
3376 size_t parsed = 0;
3377
3378 while (parsed < eir_len) {
3379 u8 field_len = eir[0];
3380
3381 if (field_len == 0)
3382 return parsed;
3383
3384 parsed += field_len + 1;
3385 eir += field_len + 1;
3386 }
3387
3388 return eir_len;
3389}
3390
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003391static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3392 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003393{
3394 struct inquiry_data data;
3395 struct extended_inquiry_info *info = (void *) (skb->data + 1);
3396 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303397 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003398
3399 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3400
3401 if (!num_rsp)
3402 return;
3403
Andre Guedes1519cc12012-03-21 00:03:38 -03003404 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3405 return;
3406
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003407 hci_dev_lock(hdev);
3408
Johan Hedberge17acd42011-03-30 23:57:16 +03003409 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003410 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003411
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003412 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003413 data.pscan_rep_mode = info->pscan_rep_mode;
3414 data.pscan_period_mode = info->pscan_period_mode;
3415 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003416 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003417 data.clock_offset = info->clock_offset;
3418 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003419 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003420
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003421 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003422 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003423 sizeof(info->data),
3424 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003425 else
3426 name_known = true;
3427
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003428 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003429 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303430 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003431 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003432 info->dev_class, info->rssi, !name_known,
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02003433 ssp, info->data, eir_len, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003434 }
3435
3436 hci_dev_unlock(hdev);
3437}
3438
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003439static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3440 struct sk_buff *skb)
3441{
3442 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3443 struct hci_conn *conn;
3444
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003445 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003446 __le16_to_cpu(ev->handle));
3447
3448 hci_dev_lock(hdev);
3449
3450 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3451 if (!conn)
3452 goto unlock;
3453
Johan Hedberg9eb1fbf2014-04-11 12:02:31 -07003454 /* For BR/EDR the necessary steps are taken through the
3455 * auth_complete event.
3456 */
3457 if (conn->type != LE_LINK)
3458 goto unlock;
3459
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003460 if (!ev->status)
3461 conn->sec_level = conn->pending_sec_level;
3462
3463 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3464
3465 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003466 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003467 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003468 goto unlock;
3469 }
3470
3471 if (conn->state == BT_CONFIG) {
3472 if (!ev->status)
3473 conn->state = BT_CONNECTED;
3474
3475 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003476 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003477 } else {
3478 hci_auth_cfm(conn, ev->status);
3479
3480 hci_conn_hold(conn);
3481 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003482 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003483 }
3484
3485unlock:
3486 hci_dev_unlock(hdev);
3487}
3488
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003489static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003490{
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003491 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003492 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3493 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003494 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003495
Mikel Astizb7f94c82014-04-08 14:21:31 +02003496 /* If both remote and local have enough IO capabilities, require
3497 * MITM protection
3498 */
3499 if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT &&
3500 conn->io_capability != HCI_IO_NO_INPUT_OUTPUT)
3501 return conn->remote_auth | 0x01;
3502
Timo Mueller7e741702014-04-08 14:21:33 +02003503 /* No MITM protection possible so ignore remote requirement */
3504 return (conn->remote_auth & ~0x01) | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003505}
3506
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003507static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003508{
3509 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3510 struct hci_conn *conn;
3511
3512 BT_DBG("%s", hdev->name);
3513
3514 hci_dev_lock(hdev);
3515
3516 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003517 if (!conn)
3518 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003519
Johan Hedberg03b555e2011-01-04 15:40:05 +02003520 hci_conn_hold(conn);
3521
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003522 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003523 goto unlock;
3524
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003525 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003526 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003527 struct hci_cp_io_capability_reply cp;
3528
3529 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303530 /* Change the IO capability from KeyboardDisplay
3531 * to DisplayYesNo as it is not supported by BT spec. */
3532 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003533 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Mikel Astizb7f94c82014-04-08 14:21:31 +02003534
3535 /* If we are initiators, there is no remote information yet */
3536 if (conn->remote_auth == 0xff) {
3537 cp.authentication = conn->auth_type;
Mikel Astiz6fd6b912014-04-08 14:21:32 +02003538
Mikel Astizb16c6602014-04-08 14:21:34 +02003539 /* Request MITM protection if our IO caps allow it
3540 * except for the no-bonding case
3541 */
Mikel Astiz6fd6b912014-04-08 14:21:32 +02003542 if (conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
Mikel Astizb16c6602014-04-08 14:21:34 +02003543 cp.authentication != HCI_AT_NO_BONDING)
Mikel Astiz6fd6b912014-04-08 14:21:32 +02003544 cp.authentication |= 0x01;
Mikel Astizb7f94c82014-04-08 14:21:31 +02003545 } else {
3546 conn->auth_type = hci_get_auth_req(conn);
3547 cp.authentication = conn->auth_type;
3548 }
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003549
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003550 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3551 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003552 cp.oob_data = 0x01;
3553 else
3554 cp.oob_data = 0x00;
3555
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003556 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003557 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003558 } else {
3559 struct hci_cp_io_capability_neg_reply cp;
3560
3561 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003562 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003563
3564 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003565 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003566 }
3567
3568unlock:
3569 hci_dev_unlock(hdev);
3570}
3571
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003572static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003573{
3574 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3575 struct hci_conn *conn;
3576
3577 BT_DBG("%s", hdev->name);
3578
3579 hci_dev_lock(hdev);
3580
3581 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3582 if (!conn)
3583 goto unlock;
3584
Johan Hedberg03b555e2011-01-04 15:40:05 +02003585 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003586 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003587 if (ev->oob_data)
3588 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003589
3590unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003591 hci_dev_unlock(hdev);
3592}
3593
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003594static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3595 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003596{
3597 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003598 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003599 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003600
3601 BT_DBG("%s", hdev->name);
3602
3603 hci_dev_lock(hdev);
3604
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003605 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003606 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003607
Johan Hedberg7a828902011-04-28 11:28:53 -07003608 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3609 if (!conn)
3610 goto unlock;
3611
3612 loc_mitm = (conn->auth_type & 0x01);
3613 rem_mitm = (conn->remote_auth & 0x01);
3614
3615 /* If we require MITM but the remote device can't provide that
Mikel Astiz6fd6b912014-04-08 14:21:32 +02003616 * (it has NoInputNoOutput) then reject the confirmation request
3617 */
3618 if (loc_mitm && conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003619 BT_DBG("Rejecting request: remote device can't provide MITM");
3620 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003621 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003622 goto unlock;
3623 }
3624
3625 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003626 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3627 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003628
3629 /* If we're not the initiators request authorization to
3630 * proceed from user space (mgmt_user_confirm with
3631 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003632 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003633 BT_DBG("Confirming auto-accept as acceptor");
3634 confirm_hint = 1;
3635 goto confirm;
3636 }
3637
Johan Hedberg9f616562011-04-28 11:28:54 -07003638 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003639 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003640
3641 if (hdev->auto_accept_delay > 0) {
3642 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
Johan Hedberg7bc18d92013-10-16 18:11:39 +03003643 queue_delayed_work(conn->hdev->workqueue,
3644 &conn->auto_accept_work, delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003645 goto unlock;
3646 }
3647
Johan Hedberg7a828902011-04-28 11:28:53 -07003648 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003649 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003650 goto unlock;
3651 }
3652
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003653confirm:
Johan Hedberg39adbff2014-03-20 08:18:14 +02003654 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0,
3655 le32_to_cpu(ev->passkey), confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003656
3657unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003658 hci_dev_unlock(hdev);
3659}
3660
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003661static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3662 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003663{
3664 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3665
3666 BT_DBG("%s", hdev->name);
3667
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003668 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003669 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003670}
3671
Johan Hedberg92a25252012-09-06 18:39:26 +03003672static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3673 struct sk_buff *skb)
3674{
3675 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3676 struct hci_conn *conn;
3677
3678 BT_DBG("%s", hdev->name);
3679
3680 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3681 if (!conn)
3682 return;
3683
3684 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3685 conn->passkey_entered = 0;
3686
3687 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3688 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3689 conn->dst_type, conn->passkey_notify,
3690 conn->passkey_entered);
3691}
3692
3693static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3694{
3695 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3696 struct hci_conn *conn;
3697
3698 BT_DBG("%s", hdev->name);
3699
3700 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3701 if (!conn)
3702 return;
3703
3704 switch (ev->type) {
3705 case HCI_KEYPRESS_STARTED:
3706 conn->passkey_entered = 0;
3707 return;
3708
3709 case HCI_KEYPRESS_ENTERED:
3710 conn->passkey_entered++;
3711 break;
3712
3713 case HCI_KEYPRESS_ERASED:
3714 conn->passkey_entered--;
3715 break;
3716
3717 case HCI_KEYPRESS_CLEARED:
3718 conn->passkey_entered = 0;
3719 break;
3720
3721 case HCI_KEYPRESS_COMPLETED:
3722 return;
3723 }
3724
3725 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3726 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3727 conn->dst_type, conn->passkey_notify,
3728 conn->passkey_entered);
3729}
3730
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003731static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3732 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003733{
3734 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3735 struct hci_conn *conn;
3736
3737 BT_DBG("%s", hdev->name);
3738
3739 hci_dev_lock(hdev);
3740
3741 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003742 if (!conn)
3743 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003744
Johan Hedberg2a611692011-02-19 12:06:00 -03003745 /* To avoid duplicate auth_failed events to user space we check
3746 * the HCI_CONN_AUTH_PEND flag which will be set if we
3747 * initiated the authentication. A traditional auth_complete
3748 * event gets always produced as initiator and is also mapped to
3749 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003750 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003751 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003752 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003753
David Herrmann76a68ba2013-04-06 20:28:37 +02003754 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003755
3756unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003757 hci_dev_unlock(hdev);
3758}
3759
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003760static void hci_remote_host_features_evt(struct hci_dev *hdev,
3761 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003762{
3763 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3764 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003765 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003766
3767 BT_DBG("%s", hdev->name);
3768
3769 hci_dev_lock(hdev);
3770
Johan Hedbergcad718e2013-04-17 15:00:51 +03003771 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3772 if (conn)
3773 memcpy(conn->features[1], ev->features, 8);
3774
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003775 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3776 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003777 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003778
3779 hci_dev_unlock(hdev);
3780}
3781
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003782static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3783 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003784{
3785 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3786 struct oob_data *data;
3787
3788 BT_DBG("%s", hdev->name);
3789
3790 hci_dev_lock(hdev);
3791
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003792 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003793 goto unlock;
3794
Szymon Janc2763eda2011-03-22 13:12:22 +01003795 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3796 if (data) {
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003797 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
3798 struct hci_cp_remote_oob_ext_data_reply cp;
Szymon Janc2763eda2011-03-22 13:12:22 +01003799
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003800 bacpy(&cp.bdaddr, &ev->bdaddr);
3801 memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
3802 memcpy(cp.randomizer192, data->randomizer192,
3803 sizeof(cp.randomizer192));
3804 memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
3805 memcpy(cp.randomizer256, data->randomizer256,
3806 sizeof(cp.randomizer256));
Szymon Janc2763eda2011-03-22 13:12:22 +01003807
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003808 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
3809 sizeof(cp), &cp);
3810 } else {
3811 struct hci_cp_remote_oob_data_reply cp;
3812
3813 bacpy(&cp.bdaddr, &ev->bdaddr);
3814 memcpy(cp.hash, data->hash192, sizeof(cp.hash));
3815 memcpy(cp.randomizer, data->randomizer192,
3816 sizeof(cp.randomizer));
3817
3818 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
3819 sizeof(cp), &cp);
3820 }
Szymon Janc2763eda2011-03-22 13:12:22 +01003821 } else {
3822 struct hci_cp_remote_oob_data_neg_reply cp;
3823
3824 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003825 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
3826 sizeof(cp), &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003827 }
3828
Szymon Jance1ba1f12011-04-06 13:01:59 +02003829unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003830 hci_dev_unlock(hdev);
3831}
3832
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003833static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3834 struct sk_buff *skb)
3835{
3836 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3837 struct hci_conn *hcon, *bredr_hcon;
3838
3839 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3840 ev->status);
3841
3842 hci_dev_lock(hdev);
3843
3844 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3845 if (!hcon) {
3846 hci_dev_unlock(hdev);
3847 return;
3848 }
3849
3850 if (ev->status) {
3851 hci_conn_del(hcon);
3852 hci_dev_unlock(hdev);
3853 return;
3854 }
3855
3856 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3857
3858 hcon->state = BT_CONNECTED;
3859 bacpy(&hcon->dst, &bredr_hcon->dst);
3860
3861 hci_conn_hold(hcon);
3862 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003863 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003864
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003865 hci_conn_add_sysfs(hcon);
3866
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003867 amp_physical_cfm(bredr_hcon, hcon);
3868
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003869 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003870}
3871
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003872static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3873{
3874 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3875 struct hci_conn *hcon;
3876 struct hci_chan *hchan;
3877 struct amp_mgr *mgr;
3878
3879 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3880 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3881 ev->status);
3882
3883 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3884 if (!hcon)
3885 return;
3886
3887 /* Create AMP hchan */
3888 hchan = hci_chan_create(hcon);
3889 if (!hchan)
3890 return;
3891
3892 hchan->handle = le16_to_cpu(ev->handle);
3893
3894 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3895
3896 mgr = hcon->amp_mgr;
3897 if (mgr && mgr->bredr_chan) {
3898 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3899
3900 l2cap_chan_lock(bredr_chan);
3901
3902 bredr_chan->conn->mtu = hdev->block_mtu;
3903 l2cap_logical_cfm(bredr_chan, hchan, 0);
3904 hci_conn_hold(hcon);
3905
3906 l2cap_chan_unlock(bredr_chan);
3907 }
3908}
3909
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003910static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3911 struct sk_buff *skb)
3912{
3913 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3914 struct hci_chan *hchan;
3915
3916 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3917 le16_to_cpu(ev->handle), ev->status);
3918
3919 if (ev->status)
3920 return;
3921
3922 hci_dev_lock(hdev);
3923
3924 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3925 if (!hchan)
3926 goto unlock;
3927
3928 amp_destroy_logical_link(hchan, ev->reason);
3929
3930unlock:
3931 hci_dev_unlock(hdev);
3932}
3933
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003934static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3935 struct sk_buff *skb)
3936{
3937 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3938 struct hci_conn *hcon;
3939
3940 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3941
3942 if (ev->status)
3943 return;
3944
3945 hci_dev_lock(hdev);
3946
3947 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3948 if (hcon) {
3949 hcon->state = BT_CLOSED;
3950 hci_conn_del(hcon);
3951 }
3952
3953 hci_dev_unlock(hdev);
3954}
3955
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003956static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003957{
3958 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3959 struct hci_conn *conn;
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003960 struct smp_irk *irk;
Ville Tervofcd89c02011-02-10 22:38:47 -03003961
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003962 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003963
3964 hci_dev_lock(hdev);
3965
Andre Guedesb47a09b2012-07-27 15:10:15 -03003966 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003967 if (!conn) {
3968 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3969 if (!conn) {
3970 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003971 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003972 }
Andre Guedes29b79882011-05-31 14:20:54 -03003973
3974 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003975
3976 if (ev->role == LE_CONN_ROLE_MASTER) {
3977 conn->out = true;
3978 conn->link_mode |= HCI_LM_MASTER;
3979 }
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02003980
3981 /* If we didn't have a hci_conn object previously
3982 * but we're in master role this must be something
3983 * initiated using a white list. Since white list based
3984 * connections are not "first class citizens" we don't
3985 * have full tracking of them. Therefore, we go ahead
3986 * with a "best effort" approach of determining the
3987 * initiator address based on the HCI_PRIVACY flag.
3988 */
3989 if (conn->out) {
3990 conn->resp_addr_type = ev->bdaddr_type;
3991 bacpy(&conn->resp_addr, &ev->bdaddr);
3992 if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
3993 conn->init_addr_type = ADDR_LE_DEV_RANDOM;
3994 bacpy(&conn->init_addr, &hdev->rpa);
3995 } else {
3996 hci_copy_identity_address(hdev,
3997 &conn->init_addr,
3998 &conn->init_addr_type);
3999 }
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02004000 }
Johan Hedberg9489eca2014-02-28 17:45:46 +02004001 } else {
4002 cancel_delayed_work(&conn->le_conn_timeout);
Ville Tervob62f3282011-02-10 22:38:50 -03004003 }
Ville Tervofcd89c02011-02-10 22:38:47 -03004004
Johan Hedberg80c24ab2014-03-24 20:21:51 +02004005 if (!conn->out) {
4006 /* Set the responder (our side) address type based on
4007 * the advertising address type.
4008 */
4009 conn->resp_addr_type = hdev->adv_addr_type;
4010 if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM)
4011 bacpy(&conn->resp_addr, &hdev->random_addr);
4012 else
4013 bacpy(&conn->resp_addr, &hdev->bdaddr);
4014
4015 conn->init_addr_type = ev->bdaddr_type;
4016 bacpy(&conn->init_addr, &ev->bdaddr);
4017 }
Johan Hedberg7be2edb2014-02-23 19:42:17 +02004018
Marcel Holtmannedb4b462014-02-18 15:13:43 -08004019 /* Lookup the identity address from the stored connection
4020 * address and address type.
4021 *
4022 * When establishing connections to an identity address, the
4023 * connection procedure will store the resolvable random
4024 * address first. Now if it can be converted back into the
4025 * identity address, start using the identity address from
4026 * now on.
4027 */
4028 irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02004029 if (irk) {
4030 bacpy(&conn->dst, &irk->bdaddr);
4031 conn->dst_type = irk->addr_type;
4032 }
4033
Andre Guedescd17dec2012-07-27 15:10:16 -03004034 if (ev->status) {
Andre Guedes06c053f2014-02-26 20:21:41 -03004035 hci_le_conn_failed(conn, ev->status);
Andre Guedescd17dec2012-07-27 15:10:16 -03004036 goto unlock;
4037 }
4038
Johan Hedbergb644ba32012-01-17 21:48:47 +02004039 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Marcel Holtmann01fdb0f2014-02-18 14:22:19 -08004040 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03004041 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03004042
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03004043 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03004044 conn->handle = __le16_to_cpu(ev->handle);
4045 conn->state = BT_CONNECTED;
4046
Jukka Rissanen18722c22013-12-11 17:05:37 +02004047 if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
4048 set_bit(HCI_CONN_6LOWPAN, &conn->flags);
4049
Ville Tervofcd89c02011-02-10 22:38:47 -03004050 hci_conn_add_sysfs(conn);
4051
4052 hci_proto_connect_cfm(conn, ev->status);
4053
Andre Guedesa4790db2014-02-26 20:21:47 -03004054 hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type);
4055
Ville Tervofcd89c02011-02-10 22:38:47 -03004056unlock:
4057 hci_dev_unlock(hdev);
4058}
4059
Andre Guedesa4790db2014-02-26 20:21:47 -03004060/* This function requires the caller holds hdev->lock */
4061static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
4062 u8 addr_type)
4063{
4064 struct hci_conn *conn;
Andre Guedes5b906a82014-02-26 20:21:53 -03004065 struct smp_irk *irk;
4066
4067 /* If this is a resolvable address, we should resolve it and then
4068 * update address and address type variables.
4069 */
4070 irk = hci_get_irk(hdev, addr, addr_type);
4071 if (irk) {
4072 addr = &irk->bdaddr;
4073 addr_type = irk->addr_type;
4074 }
Andre Guedesa4790db2014-02-26 20:21:47 -03004075
4076 if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
4077 return;
4078
4079 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
4080 HCI_AT_NO_BONDING);
4081 if (!IS_ERR(conn))
4082 return;
4083
4084 switch (PTR_ERR(conn)) {
4085 case -EBUSY:
4086 /* If hci_connect() returns -EBUSY it means there is already
4087 * an LE connection attempt going on. Since controllers don't
4088 * support more than one connection attempt at the time, we
4089 * don't consider this an error case.
4090 */
4091 break;
4092 default:
4093 BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
4094 }
4095}
4096
Johan Hedberg4af605d2014-03-24 10:48:00 +02004097static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
4098 u8 bdaddr_type, s8 rssi, u8 *data, u8 len)
4099{
Johan Hedbergb9a63282014-03-25 10:51:52 +02004100 struct discovery_state *d = &hdev->discovery;
Johan Hedberg474ee062014-03-25 14:34:59 +02004101 bool match;
Johan Hedbergb9a63282014-03-25 10:51:52 +02004102
Johan Hedbergca5c4be2014-03-25 10:30:46 +02004103 /* Passive scanning shouldn't trigger any device found events */
4104 if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
4105 if (type == LE_ADV_IND || type == LE_ADV_DIRECT_IND)
4106 check_pending_le_conn(hdev, bdaddr, bdaddr_type);
4107 return;
4108 }
Johan Hedberg4af605d2014-03-24 10:48:00 +02004109
Johan Hedbergb9a63282014-03-25 10:51:52 +02004110 /* If there's nothing pending either store the data from this
4111 * event or send an immediate device found event if the data
4112 * should not be stored for later.
4113 */
4114 if (!has_pending_adv_report(hdev)) {
4115 /* If the report will trigger a SCAN_REQ store it for
4116 * later merging.
4117 */
4118 if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
4119 store_pending_adv_report(hdev, bdaddr, bdaddr_type,
Johan Hedbergff5cd292014-03-25 14:40:52 +02004120 rssi, data, len);
Johan Hedbergb9a63282014-03-25 10:51:52 +02004121 return;
4122 }
4123
4124 mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
4125 rssi, 0, 1, data, len, NULL, 0);
4126 return;
4127 }
4128
Johan Hedberg474ee062014-03-25 14:34:59 +02004129 /* Check if the pending report is for the same device as the new one */
4130 match = (!bacmp(bdaddr, &d->last_adv_addr) &&
4131 bdaddr_type == d->last_adv_addr_type);
4132
Johan Hedbergb9a63282014-03-25 10:51:52 +02004133 /* If the pending data doesn't match this report or this isn't a
4134 * scan response (e.g. we got a duplicate ADV_IND) then force
4135 * sending of the pending data.
4136 */
Johan Hedberg474ee062014-03-25 14:34:59 +02004137 if (type != LE_ADV_SCAN_RSP || !match) {
4138 /* Send out whatever is in the cache, but skip duplicates */
4139 if (!match)
4140 mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
Johan Hedbergff5cd292014-03-25 14:40:52 +02004141 d->last_adv_addr_type, NULL,
4142 d->last_adv_rssi, 0, 1,
4143 d->last_adv_data,
Johan Hedberg474ee062014-03-25 14:34:59 +02004144 d->last_adv_data_len, NULL, 0);
Johan Hedbergb9a63282014-03-25 10:51:52 +02004145
4146 /* If the new report will trigger a SCAN_REQ store it for
4147 * later merging.
4148 */
4149 if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
4150 store_pending_adv_report(hdev, bdaddr, bdaddr_type,
Johan Hedbergff5cd292014-03-25 14:40:52 +02004151 rssi, data, len);
Johan Hedbergb9a63282014-03-25 10:51:52 +02004152 return;
4153 }
4154
4155 /* The advertising reports cannot be merged, so clear
4156 * the pending report and send out a device found event.
4157 */
4158 clear_pending_adv_report(hdev);
Johan Hedberg5c5b93e2014-03-29 08:39:53 +02004159 mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
4160 rssi, 0, 1, data, len, NULL, 0);
Johan Hedbergb9a63282014-03-25 10:51:52 +02004161 return;
4162 }
4163
4164 /* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and
4165 * the new event is a SCAN_RSP. We can therefore proceed with
4166 * sending a merged device found event.
4167 */
4168 mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
4169 d->last_adv_addr_type, NULL, rssi, 0, 1, data, len,
4170 d->last_adv_data, d->last_adv_data_len);
4171 clear_pending_adv_report(hdev);
Johan Hedberg4af605d2014-03-24 10:48:00 +02004172}
4173
Gustavo Padovan6039aa732012-05-23 04:04:18 -03004174static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03004175{
Andre Guedese95beb42011-09-26 20:48:35 -03004176 u8 num_reports = skb->data[0];
4177 void *ptr = &skb->data[1];
Andre Guedes9aa04c92011-05-26 16:23:51 -03004178
Andre Guedesa4790db2014-02-26 20:21:47 -03004179 hci_dev_lock(hdev);
4180
Andre Guedese95beb42011-09-26 20:48:35 -03004181 while (num_reports--) {
4182 struct hci_ev_le_advertising_info *ev = ptr;
Johan Hedberg4af605d2014-03-24 10:48:00 +02004183 s8 rssi;
Andre Guedesa4790db2014-02-26 20:21:47 -03004184
Andre Guedes3c9e9192012-01-10 18:20:50 -03004185 rssi = ev->data[ev->length];
Johan Hedberg4af605d2014-03-24 10:48:00 +02004186 process_adv_report(hdev, ev->evt_type, &ev->bdaddr,
4187 ev->bdaddr_type, rssi, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03004188
Andre Guedese95beb42011-09-26 20:48:35 -03004189 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03004190 }
Andre Guedesa4790db2014-02-26 20:21:47 -03004191
4192 hci_dev_unlock(hdev);
Andre Guedes9aa04c92011-05-26 16:23:51 -03004193}
4194
Gustavo Padovan6039aa732012-05-23 04:04:18 -03004195static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004196{
4197 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
4198 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004199 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004200 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03004201 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004202
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03004203 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004204
4205 hci_dev_lock(hdev);
4206
4207 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004208 if (conn == NULL)
4209 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004210
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08004211 ltk = hci_find_ltk(hdev, ev->ediv, ev->rand, conn->out);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004212 if (ltk == NULL)
4213 goto not_found;
4214
4215 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004216 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03004217
4218 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03004219 conn->pending_sec_level = BT_SECURITY_HIGH;
4220 else
4221 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004222
Andre Guedes89cbb4d2013-07-31 16:25:29 -03004223 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004224
4225 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
4226
Claudio Takahasi5981a882013-07-25 16:34:24 -03004227 /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
4228 * temporary key used to encrypt a connection following
4229 * pairing. It is used during the Encrypted Session Setup to
4230 * distribute the keys. Later, security can be re-established
4231 * using a distributed LTK.
4232 */
4233 if (ltk->type == HCI_SMP_STK_SLAVE) {
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03004234 list_del(&ltk->list);
4235 kfree(ltk);
4236 }
4237
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004238 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004239
4240 return;
4241
4242not_found:
4243 neg.handle = ev->handle;
4244 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
4245 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004246}
4247
Gustavo Padovan6039aa732012-05-23 04:04:18 -03004248static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03004249{
4250 struct hci_ev_le_meta *le_ev = (void *) skb->data;
4251
4252 skb_pull(skb, sizeof(*le_ev));
4253
4254 switch (le_ev->subevent) {
4255 case HCI_EV_LE_CONN_COMPLETE:
4256 hci_le_conn_complete_evt(hdev, skb);
4257 break;
4258
Andre Guedes9aa04c92011-05-26 16:23:51 -03004259 case HCI_EV_LE_ADVERTISING_REPORT:
4260 hci_le_adv_report_evt(hdev, skb);
4261 break;
4262
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004263 case HCI_EV_LE_LTK_REQ:
4264 hci_le_ltk_request_evt(hdev, skb);
4265 break;
4266
Ville Tervofcd89c02011-02-10 22:38:47 -03004267 default:
4268 break;
4269 }
4270}
4271
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004272static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
4273{
4274 struct hci_ev_channel_selected *ev = (void *) skb->data;
4275 struct hci_conn *hcon;
4276
4277 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
4278
4279 skb_pull(skb, sizeof(*ev));
4280
4281 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
4282 if (!hcon)
4283 return;
4284
4285 amp_read_loc_assoc_final_data(hdev, hcon);
4286}
4287
Linus Torvalds1da177e2005-04-16 15:20:36 -07004288void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
4289{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004290 struct hci_event_hdr *hdr = (void *) skb->data;
4291 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004292
Johan Hedbergb6ddb632013-04-02 13:34:31 +03004293 hci_dev_lock(hdev);
4294
4295 /* Received events are (currently) only needed when a request is
4296 * ongoing so avoid unnecessary memory allocation.
4297 */
4298 if (hdev->req_status == HCI_REQ_PEND) {
4299 kfree_skb(hdev->recv_evt);
4300 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
4301 }
4302
4303 hci_dev_unlock(hdev);
4304
Linus Torvalds1da177e2005-04-16 15:20:36 -07004305 skb_pull(skb, HCI_EVENT_HDR_SIZE);
4306
Johan Hedberg02350a72013-04-03 21:50:29 +03004307 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02004308 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
4309 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03004310
4311 hci_req_cmd_complete(hdev, opcode, 0);
4312 }
4313
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004314 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004315 case HCI_EV_INQUIRY_COMPLETE:
4316 hci_inquiry_complete_evt(hdev, skb);
4317 break;
4318
4319 case HCI_EV_INQUIRY_RESULT:
4320 hci_inquiry_result_evt(hdev, skb);
4321 break;
4322
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004323 case HCI_EV_CONN_COMPLETE:
4324 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02004325 break;
4326
Linus Torvalds1da177e2005-04-16 15:20:36 -07004327 case HCI_EV_CONN_REQUEST:
4328 hci_conn_request_evt(hdev, skb);
4329 break;
4330
Linus Torvalds1da177e2005-04-16 15:20:36 -07004331 case HCI_EV_DISCONN_COMPLETE:
4332 hci_disconn_complete_evt(hdev, skb);
4333 break;
4334
Linus Torvalds1da177e2005-04-16 15:20:36 -07004335 case HCI_EV_AUTH_COMPLETE:
4336 hci_auth_complete_evt(hdev, skb);
4337 break;
4338
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004339 case HCI_EV_REMOTE_NAME:
4340 hci_remote_name_evt(hdev, skb);
4341 break;
4342
Linus Torvalds1da177e2005-04-16 15:20:36 -07004343 case HCI_EV_ENCRYPT_CHANGE:
4344 hci_encrypt_change_evt(hdev, skb);
4345 break;
4346
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004347 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
4348 hci_change_link_key_complete_evt(hdev, skb);
4349 break;
4350
4351 case HCI_EV_REMOTE_FEATURES:
4352 hci_remote_features_evt(hdev, skb);
4353 break;
4354
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004355 case HCI_EV_CMD_COMPLETE:
4356 hci_cmd_complete_evt(hdev, skb);
4357 break;
4358
4359 case HCI_EV_CMD_STATUS:
4360 hci_cmd_status_evt(hdev, skb);
4361 break;
4362
4363 case HCI_EV_ROLE_CHANGE:
4364 hci_role_change_evt(hdev, skb);
4365 break;
4366
4367 case HCI_EV_NUM_COMP_PKTS:
4368 hci_num_comp_pkts_evt(hdev, skb);
4369 break;
4370
4371 case HCI_EV_MODE_CHANGE:
4372 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004373 break;
4374
4375 case HCI_EV_PIN_CODE_REQ:
4376 hci_pin_code_request_evt(hdev, skb);
4377 break;
4378
4379 case HCI_EV_LINK_KEY_REQ:
4380 hci_link_key_request_evt(hdev, skb);
4381 break;
4382
4383 case HCI_EV_LINK_KEY_NOTIFY:
4384 hci_link_key_notify_evt(hdev, skb);
4385 break;
4386
4387 case HCI_EV_CLOCK_OFFSET:
4388 hci_clock_offset_evt(hdev, skb);
4389 break;
4390
Marcel Holtmanna8746412008-07-14 20:13:46 +02004391 case HCI_EV_PKT_TYPE_CHANGE:
4392 hci_pkt_type_change_evt(hdev, skb);
4393 break;
4394
Marcel Holtmann85a1e932005-08-09 20:28:02 -07004395 case HCI_EV_PSCAN_REP_MODE:
4396 hci_pscan_rep_mode_evt(hdev, skb);
4397 break;
4398
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004399 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
4400 hci_inquiry_result_with_rssi_evt(hdev, skb);
4401 break;
4402
4403 case HCI_EV_REMOTE_EXT_FEATURES:
4404 hci_remote_ext_features_evt(hdev, skb);
4405 break;
4406
4407 case HCI_EV_SYNC_CONN_COMPLETE:
4408 hci_sync_conn_complete_evt(hdev, skb);
4409 break;
4410
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004411 case HCI_EV_EXTENDED_INQUIRY_RESULT:
4412 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004413 break;
4414
Johan Hedberg1c2e0042012-06-08 23:31:13 +08004415 case HCI_EV_KEY_REFRESH_COMPLETE:
4416 hci_key_refresh_complete_evt(hdev, skb);
4417 break;
4418
Marcel Holtmann04936842008-07-14 20:13:48 +02004419 case HCI_EV_IO_CAPA_REQUEST:
4420 hci_io_capa_request_evt(hdev, skb);
4421 break;
4422
Johan Hedberg03b555e2011-01-04 15:40:05 +02004423 case HCI_EV_IO_CAPA_REPLY:
4424 hci_io_capa_reply_evt(hdev, skb);
4425 break;
4426
Johan Hedberga5c29682011-02-19 12:05:57 -03004427 case HCI_EV_USER_CONFIRM_REQUEST:
4428 hci_user_confirm_request_evt(hdev, skb);
4429 break;
4430
Brian Gix1143d452011-11-23 08:28:34 -08004431 case HCI_EV_USER_PASSKEY_REQUEST:
4432 hci_user_passkey_request_evt(hdev, skb);
4433 break;
4434
Johan Hedberg92a25252012-09-06 18:39:26 +03004435 case HCI_EV_USER_PASSKEY_NOTIFY:
4436 hci_user_passkey_notify_evt(hdev, skb);
4437 break;
4438
4439 case HCI_EV_KEYPRESS_NOTIFY:
4440 hci_keypress_notify_evt(hdev, skb);
4441 break;
4442
Marcel Holtmann04936842008-07-14 20:13:48 +02004443 case HCI_EV_SIMPLE_PAIR_COMPLETE:
4444 hci_simple_pair_complete_evt(hdev, skb);
4445 break;
4446
Marcel Holtmann41a96212008-07-14 20:13:48 +02004447 case HCI_EV_REMOTE_HOST_FEATURES:
4448 hci_remote_host_features_evt(hdev, skb);
4449 break;
4450
Ville Tervofcd89c02011-02-10 22:38:47 -03004451 case HCI_EV_LE_META:
4452 hci_le_meta_evt(hdev, skb);
4453 break;
4454
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004455 case HCI_EV_CHANNEL_SELECTED:
4456 hci_chan_selected_evt(hdev, skb);
4457 break;
4458
Szymon Janc2763eda2011-03-22 13:12:22 +01004459 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
4460 hci_remote_oob_data_request_evt(hdev, skb);
4461 break;
4462
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03004463 case HCI_EV_PHY_LINK_COMPLETE:
4464 hci_phy_link_complete_evt(hdev, skb);
4465 break;
4466
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004467 case HCI_EV_LOGICAL_LINK_COMPLETE:
4468 hci_loglink_complete_evt(hdev, skb);
4469 break;
4470
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02004471 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
4472 hci_disconn_loglink_complete_evt(hdev, skb);
4473 break;
4474
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02004475 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
4476 hci_disconn_phylink_complete_evt(hdev, skb);
4477 break;
4478
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02004479 case HCI_EV_NUM_COMP_BLOCKS:
4480 hci_num_comp_blocks_evt(hdev, skb);
4481 break;
4482
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004483 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03004484 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004485 break;
4486 }
4487
4488 kfree_skb(skb);
4489 hdev->stat.evt_rx++;
4490}