blob: 1b2221d620072b293bde4d1799e51fa84f197451 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <asm/unaligned.h>
28
29#include <net/bluetooth/bluetooth.h>
30#include <net/bluetooth/hci_core.h>
Mikel Astizf0d6a0e2012-08-09 09:52:30 +020031#include <net/bluetooth/mgmt.h>
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070032
Marcel Holtmann70247282013-10-10 14:54:15 -070033#include "a2mp.h"
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070034#include "amp.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
Linus Torvalds1da177e2005-04-16 15:20:36 -070036/* Handle HCI Event packets */
37
Marcel Holtmanna9de9242007-10-20 13:33:56 +020038static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070039{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020040 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030042 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
Andre Guedes82f47852013-04-30 15:29:34 -030044 if (status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020045 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
Andre Guedes89352e72011-11-04 14:16:53 -030047 clear_bit(HCI_INQUIRY, &hdev->flags);
Andre Guedes3e13fa12013-03-27 20:04:56 -030048 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
49 wake_up_bit(&hdev->flags, HCI_INQUIRY);
Andre Guedes89352e72011-11-04 14:16:53 -030050
Marcel Holtmanna9de9242007-10-20 13:33:56 +020051 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070052}
53
Andre Guedes4d934832012-03-21 00:03:35 -030054static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
55{
56 __u8 status = *((__u8 *) skb->data);
57
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030058 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesae854a72012-03-21 00:03:36 -030059
60 if (status)
61 return;
62
63 set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
Andre Guedes4d934832012-03-21 00:03:35 -030064}
65
Marcel Holtmanna9de9242007-10-20 13:33:56 +020066static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020068 __u8 status = *((__u8 *) skb->data);
69
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030070 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020071
72 if (status)
73 return;
74
Andre Guedesae854a72012-03-21 00:03:36 -030075 clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
76
Marcel Holtmanna9de9242007-10-20 13:33:56 +020077 hci_conn_check_pending(hdev);
78}
79
Gustavo Padovan807deac2012-05-17 00:36:24 -030080static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
81 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020082{
83 BT_DBG("%s", hdev->name);
84}
85
86static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
87{
88 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030091 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
Marcel Holtmanna9de9242007-10-20 13:33:56 +020093 if (rp->status)
94 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
Marcel Holtmanna9de9242007-10-20 13:33:56 +020096 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Marcel Holtmanna9de9242007-10-20 13:33:56 +020098 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
99 if (conn) {
100 if (rp->role)
101 conn->link_mode &= ~HCI_LM_MASTER;
102 else
103 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200105
106 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107}
108
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200109static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
110{
111 struct hci_rp_read_link_policy *rp = (void *) skb->data;
112 struct hci_conn *conn;
113
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300114 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200115
116 if (rp->status)
117 return;
118
119 hci_dev_lock(hdev);
120
121 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
122 if (conn)
123 conn->link_policy = __le16_to_cpu(rp->policy);
124
125 hci_dev_unlock(hdev);
126}
127
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200128static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200130 struct hci_rp_write_link_policy *rp = (void *) skb->data;
131 struct hci_conn *conn;
132 void *sent;
133
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300134 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200135
136 if (rp->status)
137 return;
138
139 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
140 if (!sent)
141 return;
142
143 hci_dev_lock(hdev);
144
145 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200146 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700147 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200148
149 hci_dev_unlock(hdev);
150}
151
Gustavo Padovan807deac2012-05-17 00:36:24 -0300152static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
153 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200154{
155 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
156
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300157 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200158
159 if (rp->status)
160 return;
161
162 hdev->link_policy = __le16_to_cpu(rp->policy);
163}
164
Gustavo Padovan807deac2012-05-17 00:36:24 -0300165static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
166 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200167{
168 __u8 status = *((__u8 *) skb->data);
169 void *sent;
170
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300171 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200172
173 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
174 if (!sent)
175 return;
176
177 if (!status)
178 hdev->link_policy = get_unaligned_le16(sent);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200179}
180
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200181static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
182{
183 __u8 status = *((__u8 *) skb->data);
184
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300185 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200186
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300187 clear_bit(HCI_RESET, &hdev->flags);
188
Johan Hedberga297e972012-02-21 17:55:47 +0200189 /* Reset all non-persistent flags */
Johan Hedberg2cc6fb02013-03-15 17:06:57 -0500190 hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
Andre Guedes69775ff2012-02-23 16:50:05 +0200191
192 hdev->discovery.state = DISCOVERY_STOPPED;
Johan Hedbergbbaf4442012-11-08 01:22:59 +0100193 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
194 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100195
196 memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
197 hdev->adv_data_len = 0;
Marcel Holtmannf8e808b2013-10-16 00:16:47 -0700198
199 memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
200 hdev->scan_rsp_data_len = 0;
Marcel Holtmann06f5b772013-10-19 07:09:11 -0700201
Marcel Holtmann533553f2014-03-21 12:18:10 -0700202 hdev->le_scan_type = LE_SCAN_PASSIVE;
203
Marcel Holtmann06f5b772013-10-19 07:09:11 -0700204 hdev->ssp_debug_mode = 0;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200205}
206
207static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
208{
209 __u8 status = *((__u8 *) skb->data);
210 void *sent;
211
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300212 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200213
214 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
215 if (!sent)
216 return;
217
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200218 hci_dev_lock(hdev);
219
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200220 if (test_bit(HCI_MGMT, &hdev->dev_flags))
221 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200222 else if (!status)
223 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200224
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200225 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200226}
227
228static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
229{
230 struct hci_rp_read_local_name *rp = (void *) skb->data;
231
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300232 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200233
234 if (rp->status)
235 return;
236
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200237 if (test_bit(HCI_SETUP, &hdev->dev_flags))
238 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200239}
240
241static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
242{
243 __u8 status = *((__u8 *) skb->data);
244 void *sent;
245
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300246 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200247
248 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
249 if (!sent)
250 return;
251
252 if (!status) {
253 __u8 param = *((__u8 *) sent);
254
255 if (param == AUTH_ENABLED)
256 set_bit(HCI_AUTH, &hdev->flags);
257 else
258 clear_bit(HCI_AUTH, &hdev->flags);
259 }
260
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200261 if (test_bit(HCI_MGMT, &hdev->dev_flags))
262 mgmt_auth_enable_complete(hdev, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200263}
264
265static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
266{
267 __u8 status = *((__u8 *) skb->data);
268 void *sent;
269
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300270 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200271
272 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
273 if (!sent)
274 return;
275
276 if (!status) {
277 __u8 param = *((__u8 *) sent);
278
279 if (param)
280 set_bit(HCI_ENCRYPT, &hdev->flags);
281 else
282 clear_bit(HCI_ENCRYPT, &hdev->flags);
283 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200284}
285
286static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
287{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200288 __u8 param, status = *((__u8 *) skb->data);
289 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200290 void *sent;
291
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300292 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200293
294 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
295 if (!sent)
296 return;
297
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200298 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200299
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200300 hci_dev_lock(hdev);
301
Mikel Astizfa1bd912012-08-09 09:52:29 +0200302 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200303 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200304 hdev->discov_timeout = 0;
305 goto done;
306 }
307
Johan Hedberg0663ca22013-10-02 13:43:14 +0300308 /* We need to ensure that we set this back on if someone changed
309 * the scan mode through a raw HCI socket.
310 */
311 set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
312
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200313 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
314 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200315
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200316 if (param & SCAN_INQUIRY) {
317 set_bit(HCI_ISCAN, &hdev->flags);
318 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200319 mgmt_discoverable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200320 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200321 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200322
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200323 if (param & SCAN_PAGE) {
324 set_bit(HCI_PSCAN, &hdev->flags);
325 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200326 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200327 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200328 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200329
330done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200331 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200332}
333
334static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
335{
336 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
337
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300338 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200339
340 if (rp->status)
341 return;
342
343 memcpy(hdev->dev_class, rp->dev_class, 3);
344
345 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300346 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200347}
348
349static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
350{
351 __u8 status = *((__u8 *) skb->data);
352 void *sent;
353
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300354 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200355
356 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
357 if (!sent)
358 return;
359
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100360 hci_dev_lock(hdev);
361
362 if (status == 0)
363 memcpy(hdev->dev_class, sent, 3);
364
365 if (test_bit(HCI_MGMT, &hdev->dev_flags))
366 mgmt_set_class_of_dev_complete(hdev, sent, status);
367
368 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200369}
370
371static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
372{
373 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200375
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300376 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200377
378 if (rp->status)
379 return;
380
381 setting = __le16_to_cpu(rp->voice_setting);
382
Marcel Holtmannf383f272008-07-14 20:13:47 +0200383 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200384 return;
385
386 hdev->voice_setting = setting;
387
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300388 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200390 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200391 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392}
393
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300394static void hci_cc_write_voice_setting(struct hci_dev *hdev,
395 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200396{
397 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200398 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 void *sent;
400
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300401 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
Marcel Holtmannf383f272008-07-14 20:13:47 +0200403 if (status)
404 return;
405
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200406 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
407 if (!sent)
408 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
Marcel Holtmannf383f272008-07-14 20:13:47 +0200412 if (hdev->voice_setting == setting)
413 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Marcel Holtmannf383f272008-07-14 20:13:47 +0200415 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300417 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200418
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200419 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200420 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421}
422
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -0700423static void hci_cc_read_num_supported_iac(struct hci_dev *hdev,
424 struct sk_buff *skb)
425{
426 struct hci_rp_read_num_supported_iac *rp = (void *) skb->data;
427
428 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
429
430 if (rp->status)
431 return;
432
433 hdev->num_iac = rp->num_iac;
434
435 BT_DBG("%s num iac %d", hdev->name, hdev->num_iac);
436}
437
Marcel Holtmann333140b2008-07-14 20:13:48 +0200438static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
439{
440 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300441 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200442
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300443 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200444
Marcel Holtmann333140b2008-07-14 20:13:48 +0200445 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
446 if (!sent)
447 return;
448
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300449 if (!status) {
450 if (sent->mode)
Johan Hedbergcad718e2013-04-17 15:00:51 +0300451 hdev->features[1][0] |= LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300452 else
Johan Hedbergcad718e2013-04-17 15:00:51 +0300453 hdev->features[1][0] &= ~LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300454 }
455
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200456 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300457 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200458 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300459 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200460 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
461 else
462 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
463 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200464}
465
Marcel Holtmanneac83dc2014-01-10 02:07:23 -0800466static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb)
467{
468 u8 status = *((u8 *) skb->data);
469 struct hci_cp_write_sc_support *sent;
470
471 BT_DBG("%s status 0x%2.2x", hdev->name, status);
472
473 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
474 if (!sent)
475 return;
476
477 if (!status) {
478 if (sent->support)
479 hdev->features[1][0] |= LMP_HOST_SC;
480 else
481 hdev->features[1][0] &= ~LMP_HOST_SC;
482 }
483
484 if (test_bit(HCI_MGMT, &hdev->dev_flags))
485 mgmt_sc_enable_complete(hdev, sent->support, status);
486 else if (!status) {
487 if (sent->support)
488 set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
489 else
490 clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
491 }
492}
493
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200494static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
495{
496 struct hci_rp_read_local_version *rp = (void *) skb->data;
497
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300498 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200499
500 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200501 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200502
Marcel Holtmann0d5551f2013-10-18 12:04:50 -0700503 if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
504 hdev->hci_ver = rp->hci_ver;
505 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
506 hdev->lmp_ver = rp->lmp_ver;
507 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
508 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
509 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200510}
511
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300512static void hci_cc_read_local_commands(struct hci_dev *hdev,
513 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200514{
515 struct hci_rp_read_local_commands *rp = (void *) skb->data;
516
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300517 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200518
Marcel Holtmann6a070e62013-10-31 04:54:33 -0700519 if (rp->status)
520 return;
521
522 if (test_bit(HCI_SETUP, &hdev->dev_flags))
Johan Hedberg2177bab2013-03-05 20:37:43 +0200523 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200524}
525
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300526static void hci_cc_read_local_features(struct hci_dev *hdev,
527 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200528{
529 struct hci_rp_read_local_features *rp = (void *) skb->data;
530
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300531 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200532
533 if (rp->status)
534 return;
535
536 memcpy(hdev->features, rp->features, 8);
537
538 /* Adjust default settings according to features
539 * supported by device. */
540
Johan Hedbergcad718e2013-04-17 15:00:51 +0300541 if (hdev->features[0][0] & LMP_3SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200542 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
543
Johan Hedbergcad718e2013-04-17 15:00:51 +0300544 if (hdev->features[0][0] & LMP_5SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200545 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
546
Johan Hedbergcad718e2013-04-17 15:00:51 +0300547 if (hdev->features[0][1] & LMP_HV2) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200548 hdev->pkt_type |= (HCI_HV2);
549 hdev->esco_type |= (ESCO_HV2);
550 }
551
Johan Hedbergcad718e2013-04-17 15:00:51 +0300552 if (hdev->features[0][1] & LMP_HV3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200553 hdev->pkt_type |= (HCI_HV3);
554 hdev->esco_type |= (ESCO_HV3);
555 }
556
Andre Guedes45db810f2012-07-24 15:03:49 -0300557 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200558 hdev->esco_type |= (ESCO_EV3);
559
Johan Hedbergcad718e2013-04-17 15:00:51 +0300560 if (hdev->features[0][4] & LMP_EV4)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200561 hdev->esco_type |= (ESCO_EV4);
562
Johan Hedbergcad718e2013-04-17 15:00:51 +0300563 if (hdev->features[0][4] & LMP_EV5)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200564 hdev->esco_type |= (ESCO_EV5);
565
Johan Hedbergcad718e2013-04-17 15:00:51 +0300566 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100567 hdev->esco_type |= (ESCO_2EV3);
568
Johan Hedbergcad718e2013-04-17 15:00:51 +0300569 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100570 hdev->esco_type |= (ESCO_3EV3);
571
Johan Hedbergcad718e2013-04-17 15:00:51 +0300572 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100573 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200574}
575
Andre Guedes971e3a42011-06-30 19:20:52 -0300576static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300577 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300578{
579 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
580
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300581 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300582
583 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200584 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300585
Marcel Holtmann57af75a2013-10-18 12:04:47 -0700586 if (hdev->max_page < rp->max_page)
587 hdev->max_page = rp->max_page;
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300588
Johan Hedbergcad718e2013-04-17 15:00:51 +0300589 if (rp->page < HCI_MAX_PAGES)
590 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300591}
592
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200593static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300594 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200595{
596 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
597
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300598 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200599
Johan Hedberg42c6b122013-03-05 20:37:49 +0200600 if (!rp->status)
601 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200602}
603
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200604static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
605{
606 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
607
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300608 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200609
610 if (rp->status)
611 return;
612
613 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
614 hdev->sco_mtu = rp->sco_mtu;
615 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
616 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
617
618 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
619 hdev->sco_mtu = 64;
620 hdev->sco_pkts = 8;
621 }
622
623 hdev->acl_cnt = hdev->acl_pkts;
624 hdev->sco_cnt = hdev->sco_pkts;
625
Gustavo Padovan807deac2012-05-17 00:36:24 -0300626 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
627 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200628}
629
630static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
631{
632 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
633
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300634 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200635
636 if (!rp->status)
637 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200638}
639
Johan Hedbergf332ec62013-03-15 17:07:11 -0500640static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
641 struct sk_buff *skb)
642{
643 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
644
645 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
646
647 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
648 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
649 hdev->page_scan_window = __le16_to_cpu(rp->window);
650 }
651}
652
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500653static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
654 struct sk_buff *skb)
655{
656 u8 status = *((u8 *) skb->data);
657 struct hci_cp_write_page_scan_activity *sent;
658
659 BT_DBG("%s status 0x%2.2x", hdev->name, status);
660
661 if (status)
662 return;
663
664 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
665 if (!sent)
666 return;
667
668 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
669 hdev->page_scan_window = __le16_to_cpu(sent->window);
670}
671
Johan Hedbergf332ec62013-03-15 17:07:11 -0500672static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
673 struct sk_buff *skb)
674{
675 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
676
677 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
678
679 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
680 hdev->page_scan_type = rp->type;
681}
682
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500683static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
684 struct sk_buff *skb)
685{
686 u8 status = *((u8 *) skb->data);
687 u8 *type;
688
689 BT_DBG("%s status 0x%2.2x", hdev->name, status);
690
691 if (status)
692 return;
693
694 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
695 if (type)
696 hdev->page_scan_type = *type;
697}
698
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200699static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300700 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200701{
702 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
703
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300704 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200705
706 if (rp->status)
707 return;
708
709 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
710 hdev->block_len = __le16_to_cpu(rp->block_len);
711 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
712
713 hdev->block_cnt = hdev->num_blocks;
714
715 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300716 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200717}
718
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300719static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300720 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300721{
722 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
723
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300724 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300725
726 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300727 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300728
729 hdev->amp_status = rp->amp_status;
730 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
731 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
732 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
733 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
734 hdev->amp_type = rp->amp_type;
735 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
736 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
737 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
738 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
739
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300740a2mp_rsp:
741 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300742}
743
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300744static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
745 struct sk_buff *skb)
746{
747 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
748 struct amp_assoc *assoc = &hdev->loc_assoc;
749 size_t rem_len, frag_len;
750
751 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
752
753 if (rp->status)
754 goto a2mp_rsp;
755
756 frag_len = skb->len - sizeof(*rp);
757 rem_len = __le16_to_cpu(rp->rem_len);
758
759 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300760 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300761
762 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
763 assoc->offset += frag_len;
764
765 /* Read other fragments */
766 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
767
768 return;
769 }
770
771 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
772 assoc->len = assoc->offset + rem_len;
773 assoc->offset = 0;
774
775a2mp_rsp:
776 /* Send A2MP Rsp when all fragments are received */
777 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300778 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300779}
780
Johan Hedbergd5859e22011-01-25 01:19:58 +0200781static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300782 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200783{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700784 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200785
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300786 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200787
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700788 if (!rp->status)
789 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200790}
791
Johan Hedberg980e1a52011-01-22 06:10:07 +0200792static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
793{
794 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
795 struct hci_cp_pin_code_reply *cp;
796 struct hci_conn *conn;
797
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300798 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200799
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200800 hci_dev_lock(hdev);
801
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200802 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200803 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200804
Mikel Astizfa1bd912012-08-09 09:52:29 +0200805 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200806 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200807
808 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
809 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200810 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200811
812 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
813 if (conn)
814 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200815
816unlock:
817 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200818}
819
820static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
821{
822 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
823
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300824 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200825
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200826 hci_dev_lock(hdev);
827
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200828 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200829 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300830 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200831
832 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200833}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200834
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300835static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
836 struct sk_buff *skb)
837{
838 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
839
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300840 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300841
842 if (rp->status)
843 return;
844
845 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
846 hdev->le_pkts = rp->le_max_pkt;
847
848 hdev->le_cnt = hdev->le_pkts;
849
850 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300851}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200852
Johan Hedberg60e77322013-01-22 14:01:59 +0200853static void hci_cc_le_read_local_features(struct hci_dev *hdev,
854 struct sk_buff *skb)
855{
856 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
857
858 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
859
860 if (!rp->status)
861 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200862}
863
Johan Hedberg8fa19092012-10-19 20:57:49 +0300864static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
865 struct sk_buff *skb)
866{
867 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
868
869 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
870
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500871 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300872 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300873}
874
Johan Hedberga5c29682011-02-19 12:05:57 -0300875static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
876{
877 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
878
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300879 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300880
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200881 hci_dev_lock(hdev);
882
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200883 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300884 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
885 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200886
887 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300888}
889
890static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300891 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300892{
893 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
894
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300895 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300896
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200897 hci_dev_lock(hdev);
898
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200899 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200900 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300901 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200902
903 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300904}
905
Brian Gix1143d452011-11-23 08:28:34 -0800906static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
907{
908 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
909
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300910 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800911
912 hci_dev_lock(hdev);
913
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200914 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200915 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300916 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800917
918 hci_dev_unlock(hdev);
919}
920
921static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300922 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800923{
924 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
925
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300926 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800927
928 hci_dev_lock(hdev);
929
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200930 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800931 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300932 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800933
934 hci_dev_unlock(hdev);
935}
936
Marcel Holtmann4d2d2792014-01-10 02:07:26 -0800937static void hci_cc_read_local_oob_data(struct hci_dev *hdev,
938 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100939{
940 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
941
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300942 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100943
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200944 hci_dev_lock(hdev);
Marcel Holtmann4d2d2792014-01-10 02:07:26 -0800945 mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->randomizer,
946 NULL, NULL, rp->status);
947 hci_dev_unlock(hdev);
948}
949
950static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev,
951 struct sk_buff *skb)
952{
953 struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data;
954
955 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
956
957 hci_dev_lock(hdev);
958 mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->randomizer192,
959 rp->hash256, rp->randomizer256,
960 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200961 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100962}
963
Marcel Holtmann7a4cd512014-02-19 19:52:13 -0800964
965static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb)
966{
967 __u8 status = *((__u8 *) skb->data);
968 bdaddr_t *sent;
969
970 BT_DBG("%s status 0x%2.2x", hdev->name, status);
971
972 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
973 if (!sent)
974 return;
975
976 hci_dev_lock(hdev);
977
978 if (!status)
979 bacpy(&hdev->random_addr, sent);
980
981 hci_dev_unlock(hdev);
982}
983
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100984static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
985{
986 __u8 *sent, status = *((__u8 *) skb->data);
987
988 BT_DBG("%s status 0x%2.2x", hdev->name, status);
989
990 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
991 if (!sent)
992 return;
993
Johan Hedberg3c857752014-03-25 10:30:49 +0200994 if (status)
995 return;
996
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100997 hci_dev_lock(hdev);
998
Johan Hedberg3c857752014-03-25 10:30:49 +0200999 /* If we're doing connection initation as peripheral. Set a
1000 * timeout in case something goes wrong.
1001 */
1002 if (*sent) {
1003 struct hci_conn *conn;
1004
1005 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
1006 if (conn)
1007 queue_delayed_work(hdev->workqueue,
1008 &conn->le_conn_timeout,
1009 HCI_LE_CONN_TIMEOUT);
1010 }
1011
1012 mgmt_advertising(hdev, *sent);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01001013
Johan Hedberg04b4edc2013-03-15 17:07:01 -05001014 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01001015}
1016
Marcel Holtmann533553f2014-03-21 12:18:10 -07001017static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1018{
1019 struct hci_cp_le_set_scan_param *cp;
1020 __u8 status = *((__u8 *) skb->data);
1021
1022 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1023
1024 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM);
1025 if (!cp)
1026 return;
1027
1028 hci_dev_lock(hdev);
1029
1030 if (!status)
1031 hdev->le_scan_type = cp->type;
1032
1033 hci_dev_unlock(hdev);
1034}
1035
Johan Hedbergb9a63282014-03-25 10:51:52 +02001036static bool has_pending_adv_report(struct hci_dev *hdev)
1037{
1038 struct discovery_state *d = &hdev->discovery;
1039
1040 return bacmp(&d->last_adv_addr, BDADDR_ANY);
1041}
1042
1043static void clear_pending_adv_report(struct hci_dev *hdev)
1044{
1045 struct discovery_state *d = &hdev->discovery;
1046
1047 bacpy(&d->last_adv_addr, BDADDR_ANY);
1048 d->last_adv_data_len = 0;
1049}
1050
1051static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
1052 u8 bdaddr_type, u8 *data, u8 len)
1053{
1054 struct discovery_state *d = &hdev->discovery;
1055
1056 bacpy(&d->last_adv_addr, bdaddr);
1057 d->last_adv_addr_type = bdaddr_type;
1058 memcpy(d->last_adv_data, data, len);
1059 d->last_adv_data_len = len;
1060}
1061
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001062static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001063 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001064{
1065 struct hci_cp_le_set_scan_enable *cp;
1066 __u8 status = *((__u8 *) skb->data);
1067
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001068 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001069
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001070 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1071 if (!cp)
1072 return;
1073
Andre Guedes3fd319b2013-04-30 15:29:36 -03001074 if (status)
1075 return;
1076
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001077 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -03001078 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -03001079 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Johan Hedbergb9a63282014-03-25 10:51:52 +02001080 if (hdev->le_scan_type == LE_SCAN_ACTIVE)
1081 clear_pending_adv_report(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001082 break;
1083
Andre Guedes76a388b2013-04-04 20:21:02 -03001084 case LE_SCAN_DISABLE:
Johan Hedbergb9a63282014-03-25 10:51:52 +02001085 /* We do this here instead of when setting DISCOVERY_STOPPED
1086 * since the latter would potentially require waiting for
1087 * inquiry to stop too.
1088 */
1089 if (has_pending_adv_report(hdev)) {
1090 struct discovery_state *d = &hdev->discovery;
1091
1092 mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
1093 d->last_adv_addr_type, NULL, 0, 0,
1094 1, d->last_adv_data,
1095 d->last_adv_data_len, NULL, 0);
1096 }
1097
Johan Hedberg317ac8c2014-02-28 20:26:12 +02001098 /* Cancel this timer so that we don't try to disable scanning
1099 * when it's already disabled.
1100 */
1101 cancel_delayed_work(&hdev->le_scan_disable);
1102
Andre Guedesd23264a2011-11-25 20:53:38 -03001103 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Johan Hedberg81ad6fd2014-02-28 20:26:13 +02001104 /* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
1105 * interrupted scanning due to a connect request. Mark
1106 * therefore discovery as stopped.
1107 */
1108 if (test_and_clear_bit(HCI_LE_SCAN_INTERRUPTED,
1109 &hdev->dev_flags))
1110 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001111 break;
1112
1113 default:
1114 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1115 break;
Andre Guedes35815082011-05-26 16:23:53 -03001116 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001117}
1118
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001119static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
1120 struct sk_buff *skb)
1121{
1122 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
1123
1124 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
1125
1126 if (!rp->status)
1127 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001128}
1129
Marcel Holtmann0f36b582014-02-27 20:37:31 -08001130static void hci_cc_le_clear_white_list(struct hci_dev *hdev,
1131 struct sk_buff *skb)
1132{
1133 __u8 status = *((__u8 *) skb->data);
1134
1135 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1136
1137 if (!status)
1138 hci_white_list_clear(hdev);
1139}
1140
1141static void hci_cc_le_add_to_white_list(struct hci_dev *hdev,
1142 struct sk_buff *skb)
1143{
1144 struct hci_cp_le_add_to_white_list *sent;
1145 __u8 status = *((__u8 *) skb->data);
1146
1147 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1148
1149 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST);
1150 if (!sent)
1151 return;
1152
1153 if (!status)
1154 hci_white_list_add(hdev, &sent->bdaddr, sent->bdaddr_type);
1155}
1156
1157static void hci_cc_le_del_from_white_list(struct hci_dev *hdev,
1158 struct sk_buff *skb)
1159{
1160 struct hci_cp_le_del_from_white_list *sent;
1161 __u8 status = *((__u8 *) skb->data);
1162
1163 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1164
1165 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST);
1166 if (!sent)
1167 return;
1168
1169 if (!status)
1170 hci_white_list_del(hdev, &sent->bdaddr, sent->bdaddr_type);
1171}
1172
Johan Hedberg9b008c02013-01-22 14:02:01 +02001173static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
1174 struct sk_buff *skb)
1175{
1176 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
1177
1178 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1179
1180 if (!rp->status)
1181 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +02001182}
1183
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001184static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1185 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001186{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001187 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001188 __u8 status = *((__u8 *) skb->data);
1189
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001190 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001191
Johan Hedberg06199cf2012-02-22 16:37:11 +02001192 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001193 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001194 return;
1195
Johan Hedberg8f984df2012-02-28 01:07:22 +02001196 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001197 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001198 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001199 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1200 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001201 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001202 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001203 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001204 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001205
1206 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001207 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001208 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001209 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001210 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001211}
1212
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02001213static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
1214{
1215 struct hci_cp_le_set_adv_param *cp;
1216 u8 status = *((u8 *) skb->data);
1217
1218 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1219
1220 if (status)
1221 return;
1222
1223 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM);
1224 if (!cp)
1225 return;
1226
1227 hci_dev_lock(hdev);
1228 hdev->adv_addr_type = cp->own_address_type;
1229 hci_dev_unlock(hdev);
1230}
1231
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001232static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1233 struct sk_buff *skb)
1234{
1235 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1236
1237 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1238 hdev->name, rp->status, rp->phy_handle);
1239
1240 if (rp->status)
1241 return;
1242
1243 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1244}
1245
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001246static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001247{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001248 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001249
1250 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001251 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001252 return;
1253 }
1254
Andre Guedes89352e72011-11-04 14:16:53 -03001255 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001256}
1257
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001258static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001259{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001260 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001263 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001264
1265 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266 if (!cp)
1267 return;
1268
1269 hci_dev_lock(hdev);
1270
1271 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1272
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001273 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274
1275 if (status) {
1276 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001277 if (status != 0x0c || conn->attempt > 2) {
1278 conn->state = BT_CLOSED;
1279 hci_proto_connect_cfm(conn, status);
1280 hci_conn_del(conn);
1281 } else
1282 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001283 }
1284 } else {
1285 if (!conn) {
1286 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1287 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001288 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001289 conn->link_mode |= HCI_LM_MASTER;
1290 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001291 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292 }
1293 }
1294
1295 hci_dev_unlock(hdev);
1296}
1297
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001298static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001300 struct hci_cp_add_sco *cp;
1301 struct hci_conn *acl, *sco;
1302 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001303
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001304 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001305
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001306 if (!status)
1307 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001309 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1310 if (!cp)
1311 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001313 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001315 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001316
1317 hci_dev_lock(hdev);
1318
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001319 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001320 if (acl) {
1321 sco = acl->link;
1322 if (sco) {
1323 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001324
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001325 hci_proto_connect_cfm(sco, status);
1326 hci_conn_del(sco);
1327 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001328 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001329
1330 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331}
1332
Marcel Holtmannf8558552008-07-14 20:13:49 +02001333static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1334{
1335 struct hci_cp_auth_requested *cp;
1336 struct hci_conn *conn;
1337
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001338 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001339
1340 if (!status)
1341 return;
1342
1343 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1344 if (!cp)
1345 return;
1346
1347 hci_dev_lock(hdev);
1348
1349 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1350 if (conn) {
1351 if (conn->state == BT_CONFIG) {
1352 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001353 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001354 }
1355 }
1356
1357 hci_dev_unlock(hdev);
1358}
1359
1360static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1361{
1362 struct hci_cp_set_conn_encrypt *cp;
1363 struct hci_conn *conn;
1364
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001365 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001366
1367 if (!status)
1368 return;
1369
1370 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1371 if (!cp)
1372 return;
1373
1374 hci_dev_lock(hdev);
1375
1376 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1377 if (conn) {
1378 if (conn->state == BT_CONFIG) {
1379 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001380 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001381 }
1382 }
1383
1384 hci_dev_unlock(hdev);
1385}
1386
Johan Hedberg127178d2010-11-18 22:22:29 +02001387static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001388 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001389{
Johan Hedberg392599b2010-11-18 22:22:28 +02001390 if (conn->state != BT_CONFIG || !conn->out)
1391 return 0;
1392
Johan Hedberg765c2a92011-01-19 12:06:52 +05301393 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001394 return 0;
1395
1396 /* Only request authentication for SSP connections or non-SSP
Johan Hedberg264b8b42014-01-08 16:40:39 +02001397 * devices with sec_level MEDIUM or HIGH or if MITM protection
1398 * is requested.
1399 */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001400 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
Johan Hedberg264b8b42014-01-08 16:40:39 +02001401 conn->pending_sec_level != BT_SECURITY_HIGH &&
1402 conn->pending_sec_level != BT_SECURITY_MEDIUM)
Johan Hedberg392599b2010-11-18 22:22:28 +02001403 return 0;
1404
Johan Hedberg392599b2010-11-18 22:22:28 +02001405 return 1;
1406}
1407
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001408static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001409 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001410{
1411 struct hci_cp_remote_name_req cp;
1412
1413 memset(&cp, 0, sizeof(cp));
1414
1415 bacpy(&cp.bdaddr, &e->data.bdaddr);
1416 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1417 cp.pscan_mode = e->data.pscan_mode;
1418 cp.clock_offset = e->data.clock_offset;
1419
1420 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1421}
1422
Johan Hedbergb644ba32012-01-17 21:48:47 +02001423static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001424{
1425 struct discovery_state *discov = &hdev->discovery;
1426 struct inquiry_entry *e;
1427
Johan Hedbergb644ba32012-01-17 21:48:47 +02001428 if (list_empty(&discov->resolve))
1429 return false;
1430
1431 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001432 if (!e)
1433 return false;
1434
Johan Hedbergb644ba32012-01-17 21:48:47 +02001435 if (hci_resolve_name(hdev, e) == 0) {
1436 e->name_state = NAME_PENDING;
1437 return true;
1438 }
1439
1440 return false;
1441}
1442
1443static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001444 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001445{
1446 struct discovery_state *discov = &hdev->discovery;
1447 struct inquiry_entry *e;
1448
1449 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001450 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1451 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001452
1453 if (discov->state == DISCOVERY_STOPPED)
1454 return;
1455
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001456 if (discov->state == DISCOVERY_STOPPING)
1457 goto discov_complete;
1458
1459 if (discov->state != DISCOVERY_RESOLVING)
1460 return;
1461
1462 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001463 /* If the device was not found in a list of found devices names of which
1464 * are pending. there is no need to continue resolving a next name as it
1465 * will be done upon receiving another Remote Name Request Complete
1466 * Event */
1467 if (!e)
1468 return;
1469
1470 list_del(&e->list);
1471 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001472 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001473 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1474 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001475 } else {
1476 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001477 }
1478
Johan Hedbergb644ba32012-01-17 21:48:47 +02001479 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001480 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001481
1482discov_complete:
1483 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1484}
1485
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001486static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1487{
Johan Hedberg127178d2010-11-18 22:22:29 +02001488 struct hci_cp_remote_name_req *cp;
1489 struct hci_conn *conn;
1490
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001491 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001492
1493 /* If successful wait for the name req complete event before
1494 * checking for the need to do authentication */
1495 if (!status)
1496 return;
1497
1498 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1499 if (!cp)
1500 return;
1501
1502 hci_dev_lock(hdev);
1503
1504 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001505
1506 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1507 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1508
Johan Hedberg79c6c702011-04-28 11:28:55 -07001509 if (!conn)
1510 goto unlock;
1511
1512 if (!hci_outgoing_auth_needed(hdev, conn))
1513 goto unlock;
1514
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001515 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001516 struct hci_cp_auth_requested auth_cp;
1517
1518 auth_cp.handle = __cpu_to_le16(conn->handle);
1519 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1520 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001521 }
1522
Johan Hedberg79c6c702011-04-28 11:28:55 -07001523unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001524 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001525}
1526
Marcel Holtmann769be972008-07-14 20:13:49 +02001527static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1528{
1529 struct hci_cp_read_remote_features *cp;
1530 struct hci_conn *conn;
1531
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001532 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001533
1534 if (!status)
1535 return;
1536
1537 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1538 if (!cp)
1539 return;
1540
1541 hci_dev_lock(hdev);
1542
1543 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1544 if (conn) {
1545 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001546 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001547 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001548 }
1549 }
1550
1551 hci_dev_unlock(hdev);
1552}
1553
1554static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1555{
1556 struct hci_cp_read_remote_ext_features *cp;
1557 struct hci_conn *conn;
1558
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001559 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001560
1561 if (!status)
1562 return;
1563
1564 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1565 if (!cp)
1566 return;
1567
1568 hci_dev_lock(hdev);
1569
1570 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1571 if (conn) {
1572 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001573 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001574 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001575 }
1576 }
1577
1578 hci_dev_unlock(hdev);
1579}
1580
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001581static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1582{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001583 struct hci_cp_setup_sync_conn *cp;
1584 struct hci_conn *acl, *sco;
1585 __u16 handle;
1586
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001587 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001588
1589 if (!status)
1590 return;
1591
1592 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1593 if (!cp)
1594 return;
1595
1596 handle = __le16_to_cpu(cp->handle);
1597
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001598 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001599
1600 hci_dev_lock(hdev);
1601
1602 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001603 if (acl) {
1604 sco = acl->link;
1605 if (sco) {
1606 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001607
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001608 hci_proto_connect_cfm(sco, status);
1609 hci_conn_del(sco);
1610 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001611 }
1612
1613 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001614}
1615
1616static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1617{
1618 struct hci_cp_sniff_mode *cp;
1619 struct hci_conn *conn;
1620
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001621 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001622
1623 if (!status)
1624 return;
1625
1626 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1627 if (!cp)
1628 return;
1629
1630 hci_dev_lock(hdev);
1631
1632 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001633 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001634 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001635
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001636 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001637 hci_sco_setup(conn, status);
1638 }
1639
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001640 hci_dev_unlock(hdev);
1641}
1642
1643static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1644{
1645 struct hci_cp_exit_sniff_mode *cp;
1646 struct hci_conn *conn;
1647
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001648 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001649
1650 if (!status)
1651 return;
1652
1653 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1654 if (!cp)
1655 return;
1656
1657 hci_dev_lock(hdev);
1658
1659 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001660 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001661 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001662
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001663 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001664 hci_sco_setup(conn, status);
1665 }
1666
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001667 hci_dev_unlock(hdev);
1668}
1669
Johan Hedberg88c3df12012-02-09 14:27:38 +02001670static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1671{
1672 struct hci_cp_disconnect *cp;
1673 struct hci_conn *conn;
1674
1675 if (!status)
1676 return;
1677
1678 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1679 if (!cp)
1680 return;
1681
1682 hci_dev_lock(hdev);
1683
1684 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1685 if (conn)
1686 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001687 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001688
1689 hci_dev_unlock(hdev);
1690}
1691
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001692static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1693{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001694 struct hci_cp_create_phy_link *cp;
1695
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001696 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001697
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001698 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1699 if (!cp)
1700 return;
1701
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001702 hci_dev_lock(hdev);
1703
1704 if (status) {
1705 struct hci_conn *hcon;
1706
1707 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1708 if (hcon)
1709 hci_conn_del(hcon);
1710 } else {
1711 amp_write_remote_assoc(hdev, cp->phy_handle);
1712 }
1713
1714 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001715}
1716
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001717static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1718{
1719 struct hci_cp_accept_phy_link *cp;
1720
1721 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1722
1723 if (status)
1724 return;
1725
1726 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1727 if (!cp)
1728 return;
1729
1730 amp_write_remote_assoc(hdev, cp->phy_handle);
1731}
1732
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02001733static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
1734{
1735 struct hci_cp_le_create_conn *cp;
1736 struct hci_conn *conn;
1737
1738 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1739
1740 /* All connection failure handling is taken care of by the
1741 * hci_le_conn_failed function which is triggered by the HCI
1742 * request completion callbacks used for connecting.
1743 */
1744 if (status)
1745 return;
1746
1747 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1748 if (!cp)
1749 return;
1750
1751 hci_dev_lock(hdev);
1752
1753 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1754 if (!conn)
1755 goto unlock;
1756
1757 /* Store the initiator and responder address information which
1758 * is needed for SMP. These values will not change during the
1759 * lifetime of the connection.
1760 */
1761 conn->init_addr_type = cp->own_address_type;
1762 if (cp->own_address_type == ADDR_LE_DEV_RANDOM)
1763 bacpy(&conn->init_addr, &hdev->random_addr);
1764 else
1765 bacpy(&conn->init_addr, &hdev->bdaddr);
1766
1767 conn->resp_addr_type = cp->peer_addr_type;
1768 bacpy(&conn->resp_addr, &cp->peer_addr);
1769
Johan Hedberg9489eca2014-02-28 17:45:46 +02001770 /* We don't want the connection attempt to stick around
1771 * indefinitely since LE doesn't have a page timeout concept
1772 * like BR/EDR. Set a timer for any connection that doesn't use
1773 * the white list for connecting.
1774 */
1775 if (cp->filter_policy == HCI_LE_USE_PEER_ADDR)
1776 queue_delayed_work(conn->hdev->workqueue,
1777 &conn->le_conn_timeout,
1778 HCI_LE_CONN_TIMEOUT);
1779
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02001780unlock:
1781 hci_dev_unlock(hdev);
1782}
1783
Johan Hedberg81d0c8a2014-03-24 14:39:04 +02001784static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1785{
1786 struct hci_cp_le_start_enc *cp;
1787 struct hci_conn *conn;
1788
1789 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1790
1791 if (!status)
1792 return;
1793
1794 hci_dev_lock(hdev);
1795
1796 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
1797 if (!cp)
1798 goto unlock;
1799
1800 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1801 if (!conn)
1802 goto unlock;
1803
1804 if (conn->state != BT_CONNECTED)
1805 goto unlock;
1806
1807 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
1808 hci_conn_drop(conn);
1809
1810unlock:
1811 hci_dev_unlock(hdev);
1812}
1813
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001814static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001815{
1816 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001817 struct discovery_state *discov = &hdev->discovery;
1818 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001819
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001820 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001821
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001822 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001823
1824 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1825 return;
1826
Andre Guedes3e13fa12013-03-27 20:04:56 -03001827 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1828 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1829
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001830 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001831 return;
1832
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001833 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001834
Andre Guedes343f9352012-02-17 20:39:37 -03001835 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001836 goto unlock;
1837
1838 if (list_empty(&discov->resolve)) {
1839 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1840 goto unlock;
1841 }
1842
1843 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1844 if (e && hci_resolve_name(hdev, e) == 0) {
1845 e->name_state = NAME_PENDING;
1846 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1847 } else {
1848 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1849 }
1850
1851unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001852 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001853}
1854
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001855static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001857 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001858 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859 int num_rsp = *((__u8 *) skb->data);
1860
1861 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1862
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001863 if (!num_rsp)
1864 return;
1865
Andre Guedes1519cc12012-03-21 00:03:38 -03001866 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1867 return;
1868
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001870
Johan Hedberge17acd42011-03-30 23:57:16 +03001871 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001872 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001873
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874 bacpy(&data.bdaddr, &info->bdaddr);
1875 data.pscan_rep_mode = info->pscan_rep_mode;
1876 data.pscan_period_mode = info->pscan_period_mode;
1877 data.pscan_mode = info->pscan_mode;
1878 memcpy(data.dev_class, info->dev_class, 3);
1879 data.clock_offset = info->clock_offset;
1880 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001881 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001882
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001883 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001884 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001885 info->dev_class, 0, !name_known, ssp, NULL,
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02001886 0, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001888
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889 hci_dev_unlock(hdev);
1890}
1891
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001892static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001894 struct hci_ev_conn_complete *ev = (void *) skb->data;
1895 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001897 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001898
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001900
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001901 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001902 if (!conn) {
1903 if (ev->link_type != SCO_LINK)
1904 goto unlock;
1905
1906 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1907 if (!conn)
1908 goto unlock;
1909
1910 conn->type = SCO_LINK;
1911 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001912
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001913 if (!ev->status) {
1914 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001915
1916 if (conn->type == ACL_LINK) {
1917 conn->state = BT_CONFIG;
1918 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001919
1920 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1921 !hci_find_link_key(hdev, &ev->bdaddr))
1922 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1923 else
1924 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001925 } else
1926 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001927
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001928 hci_conn_add_sysfs(conn);
1929
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001930 if (test_bit(HCI_AUTH, &hdev->flags))
1931 conn->link_mode |= HCI_LM_AUTH;
1932
1933 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1934 conn->link_mode |= HCI_LM_ENCRYPT;
1935
1936 /* Get remote features */
1937 if (conn->type == ACL_LINK) {
1938 struct hci_cp_read_remote_features cp;
1939 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001940 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001941 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001942 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001943
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001944 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001945 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001946 struct hci_cp_change_conn_ptype cp;
1947 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001948 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001949 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1950 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001951 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001952 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001953 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001954 if (conn->type == ACL_LINK)
Marcel Holtmann64c7b772014-02-18 14:22:20 -08001955 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001956 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001957 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001958
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001959 if (conn->type == ACL_LINK)
1960 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001961
Marcel Holtmann769be972008-07-14 20:13:49 +02001962 if (ev->status) {
1963 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001964 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001965 } else if (ev->link_type != ACL_LINK)
1966 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001967
1968unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001970
1971 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001972}
1973
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001974static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001976 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001978 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001980 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001981 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001983 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1984 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001985
Szymon Janc138d22e2011-02-17 16:44:23 +01001986 if ((mask & HCI_LM_ACCEPT) &&
Marcel Holtmannb9ee0a72013-10-17 17:24:13 -07001987 !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001989 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001990 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991
1992 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001993
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001994 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1995 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001996 memcpy(ie->data.dev_class, ev->dev_class, 3);
1997
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001998 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1999 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002000 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002001 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
2002 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03002003 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004 hci_dev_unlock(hdev);
2005 return;
2006 }
2007 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002008
Linus Torvalds1da177e2005-04-16 15:20:36 -07002009 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002010
Linus Torvalds1da177e2005-04-16 15:20:36 -07002011 hci_dev_unlock(hdev);
2012
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002013 if (ev->link_type == ACL_LINK ||
2014 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002015 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002016 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002018 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002020 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
2021 cp.role = 0x00; /* Become master */
2022 else
2023 cp.role = 0x01; /* Remain slave */
2024
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002025 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
2026 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002027 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002028 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002029 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002030
2031 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002032 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002033
Joe Perchesdcf4adb2014-03-12 10:52:35 -07002034 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
2035 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
2036 cp.max_latency = cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002037 cp.content_format = cpu_to_le16(hdev->voice_setting);
2038 cp.retrans_effort = 0xff;
2039
2040 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002041 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01002042 } else {
2043 conn->state = BT_CONNECT2;
2044 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002045 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046 } else {
2047 /* Connection rejected */
2048 struct hci_cp_reject_conn_req cp;
2049
2050 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002051 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002052 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002053 }
2054}
2055
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02002056static u8 hci_to_mgmt_reason(u8 err)
2057{
2058 switch (err) {
2059 case HCI_ERROR_CONNECTION_TIMEOUT:
2060 return MGMT_DEV_DISCONN_TIMEOUT;
2061 case HCI_ERROR_REMOTE_USER_TERM:
2062 case HCI_ERROR_REMOTE_LOW_RESOURCES:
2063 case HCI_ERROR_REMOTE_POWER_OFF:
2064 return MGMT_DEV_DISCONN_REMOTE;
2065 case HCI_ERROR_LOCAL_HOST_TERM:
2066 return MGMT_DEV_DISCONN_LOCAL_HOST;
2067 default:
2068 return MGMT_DEV_DISCONN_UNKNOWN;
2069 }
2070}
2071
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002072static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002074 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Andre Guedesabf54a52013-11-07 17:36:09 -03002075 u8 reason = hci_to_mgmt_reason(ev->reason);
Andre Guedes9fcb18e2014-02-26 20:21:48 -03002076 struct hci_conn_params *params;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002077 struct hci_conn *conn;
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02002078 bool mgmt_connected;
Andre Guedes38462202013-11-07 17:36:10 -03002079 u8 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002080
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002081 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083 hci_dev_lock(hdev);
2084
Marcel Holtmann04837f62006-07-03 10:02:33 +02002085 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02002086 if (!conn)
2087 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002088
Andre Guedesabf54a52013-11-07 17:36:09 -03002089 if (ev->status) {
2090 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
2091 conn->dst_type, ev->status);
2092 goto unlock;
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002093 }
Johan Hedbergf7520542011-01-20 12:34:39 +02002094
Andre Guedes38462202013-11-07 17:36:10 -03002095 conn->state = BT_CLOSED;
2096
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02002097 mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
2098 mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
2099 reason, mgmt_connected);
Andre Guedesabf54a52013-11-07 17:36:09 -03002100
Andre Guedes38462202013-11-07 17:36:10 -03002101 if (conn->type == ACL_LINK && conn->flush_key)
2102 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg22102462013-10-05 12:01:06 +02002103
Andre Guedes9fcb18e2014-02-26 20:21:48 -03002104 params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
2105 if (params) {
2106 switch (params->auto_connect) {
2107 case HCI_AUTO_CONN_LINK_LOSS:
2108 if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
2109 break;
2110 /* Fall through */
2111
2112 case HCI_AUTO_CONN_ALWAYS:
2113 hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type);
2114 break;
2115
2116 default:
2117 break;
2118 }
2119 }
2120
Andre Guedes38462202013-11-07 17:36:10 -03002121 type = conn->type;
Johan Hedberg22102462013-10-05 12:01:06 +02002122
Andre Guedes38462202013-11-07 17:36:10 -03002123 hci_proto_disconn_cfm(conn, ev->reason);
2124 hci_conn_del(conn);
2125
2126 /* Re-enable advertising if necessary, since it might
2127 * have been disabled by the connection. From the
2128 * HCI_LE_Set_Advertise_Enable command description in
2129 * the core specification (v4.0):
2130 * "The Controller shall continue advertising until the Host
2131 * issues an LE_Set_Advertise_Enable command with
2132 * Advertising_Enable set to 0x00 (Advertising is disabled)
2133 * or until a connection is created or until the Advertising
2134 * is timed out due to Directed Advertising."
2135 */
2136 if (type == LE_LINK)
2137 mgmt_reenable_advertising(hdev);
Johan Hedbergf7520542011-01-20 12:34:39 +02002138
2139unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002140 hci_dev_unlock(hdev);
2141}
2142
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002143static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002144{
2145 struct hci_ev_auth_complete *ev = (void *) skb->data;
2146 struct hci_conn *conn;
2147
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002148 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002149
2150 hci_dev_lock(hdev);
2151
2152 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002153 if (!conn)
2154 goto unlock;
2155
2156 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002157 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002158 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002159 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03002160 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002161 conn->link_mode |= HCI_LM_AUTH;
2162 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03002163 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002164 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02002165 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002166 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002167 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002168
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002169 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
2170 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002171
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002172 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002173 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002174 struct hci_cp_set_conn_encrypt cp;
2175 cp.handle = ev->handle;
2176 cp.encrypt = 0x01;
2177 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002178 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002179 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002180 conn->state = BT_CONNECTED;
2181 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002182 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002183 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002184 } else {
2185 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002186
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002187 hci_conn_hold(conn);
2188 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002189 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002190 }
2191
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002192 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002193 if (!ev->status) {
2194 struct hci_cp_set_conn_encrypt cp;
2195 cp.handle = ev->handle;
2196 cp.encrypt = 0x01;
2197 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002198 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002199 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002200 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002201 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002202 }
2203 }
2204
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002205unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002206 hci_dev_unlock(hdev);
2207}
2208
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002209static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002210{
Johan Hedberg127178d2010-11-18 22:22:29 +02002211 struct hci_ev_remote_name *ev = (void *) skb->data;
2212 struct hci_conn *conn;
2213
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002214 BT_DBG("%s", hdev->name);
2215
2216 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02002217
2218 hci_dev_lock(hdev);
2219
2220 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002221
2222 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2223 goto check_auth;
2224
2225 if (ev->status == 0)
2226 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002227 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002228 else
2229 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2230
2231check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002232 if (!conn)
2233 goto unlock;
2234
2235 if (!hci_outgoing_auth_needed(hdev, conn))
2236 goto unlock;
2237
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002238 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002239 struct hci_cp_auth_requested cp;
2240 cp.handle = __cpu_to_le16(conn->handle);
2241 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2242 }
2243
Johan Hedberg79c6c702011-04-28 11:28:55 -07002244unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002245 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002246}
2247
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002248static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002249{
2250 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2251 struct hci_conn *conn;
2252
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002253 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002254
2255 hci_dev_lock(hdev);
2256
2257 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002258 if (!conn)
2259 goto unlock;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002260
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002261 if (!ev->status) {
2262 if (ev->encrypt) {
2263 /* Encryption implies authentication */
2264 conn->link_mode |= HCI_LM_AUTH;
2265 conn->link_mode |= HCI_LM_ENCRYPT;
2266 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002267
Marcel Holtmann914a6ff2014-02-01 11:52:02 -08002268 /* P-256 authentication key implies FIPS */
2269 if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
2270 conn->link_mode |= HCI_LM_FIPS;
2271
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002272 if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
2273 conn->type == LE_LINK)
2274 set_bit(HCI_CONN_AES_CCM, &conn->flags);
2275 } else {
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002276 conn->link_mode &= ~HCI_LM_ENCRYPT;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002277 clear_bit(HCI_CONN_AES_CCM, &conn->flags);
2278 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002279 }
2280
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002281 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2282
2283 if (ev->status && conn->state == BT_CONNECTED) {
2284 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
2285 hci_conn_drop(conn);
2286 goto unlock;
2287 }
2288
2289 if (conn->state == BT_CONFIG) {
2290 if (!ev->status)
2291 conn->state = BT_CONNECTED;
2292
Marcel Holtmann40b552a2014-03-19 14:10:25 -07002293 /* In Secure Connections Only mode, do not allow any
2294 * connections that are not encrypted with AES-CCM
2295 * using a P-256 authenticated combination key.
2296 */
2297 if (test_bit(HCI_SC_ONLY, &hdev->dev_flags) &&
2298 (!test_bit(HCI_CONN_AES_CCM, &conn->flags) ||
2299 conn->key_type != HCI_LK_AUTH_COMBINATION_P256)) {
2300 hci_proto_connect_cfm(conn, HCI_ERROR_AUTH_FAILURE);
2301 hci_conn_drop(conn);
2302 goto unlock;
2303 }
2304
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002305 hci_proto_connect_cfm(conn, ev->status);
2306 hci_conn_drop(conn);
2307 } else
2308 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
2309
Gustavo Padovana7d77232012-05-13 03:20:07 -03002310unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002311 hci_dev_unlock(hdev);
2312}
2313
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002314static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2315 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002316{
2317 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2318 struct hci_conn *conn;
2319
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002320 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002321
2322 hci_dev_lock(hdev);
2323
2324 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2325 if (conn) {
2326 if (!ev->status)
2327 conn->link_mode |= HCI_LM_SECURE;
2328
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002329 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002330
2331 hci_key_change_cfm(conn, ev->status);
2332 }
2333
2334 hci_dev_unlock(hdev);
2335}
2336
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002337static void hci_remote_features_evt(struct hci_dev *hdev,
2338 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002339{
2340 struct hci_ev_remote_features *ev = (void *) skb->data;
2341 struct hci_conn *conn;
2342
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002343 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002344
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002345 hci_dev_lock(hdev);
2346
2347 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002348 if (!conn)
2349 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002350
Johan Hedbergccd556f2010-11-10 17:11:51 +02002351 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002352 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002353
2354 if (conn->state != BT_CONFIG)
2355 goto unlock;
2356
2357 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2358 struct hci_cp_read_remote_ext_features cp;
2359 cp.handle = ev->handle;
2360 cp.page = 0x01;
2361 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002362 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002363 goto unlock;
2364 }
2365
Johan Hedberg671267b2012-05-12 16:11:50 -03002366 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002367 struct hci_cp_remote_name_req cp;
2368 memset(&cp, 0, sizeof(cp));
2369 bacpy(&cp.bdaddr, &conn->dst);
2370 cp.pscan_rep_mode = 0x02;
2371 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002372 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2373 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002374 conn->dst_type, 0, NULL, 0,
2375 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002376
Johan Hedberg127178d2010-11-18 22:22:29 +02002377 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002378 conn->state = BT_CONNECTED;
2379 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002380 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002381 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002382
Johan Hedbergccd556f2010-11-10 17:11:51 +02002383unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002384 hci_dev_unlock(hdev);
2385}
2386
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002387static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002388{
2389 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002390 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002391 __u16 opcode;
2392
2393 skb_pull(skb, sizeof(*ev));
2394
2395 opcode = __le16_to_cpu(ev->opcode);
2396
2397 switch (opcode) {
2398 case HCI_OP_INQUIRY_CANCEL:
2399 hci_cc_inquiry_cancel(hdev, skb);
2400 break;
2401
Andre Guedes4d934832012-03-21 00:03:35 -03002402 case HCI_OP_PERIODIC_INQ:
2403 hci_cc_periodic_inq(hdev, skb);
2404 break;
2405
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002406 case HCI_OP_EXIT_PERIODIC_INQ:
2407 hci_cc_exit_periodic_inq(hdev, skb);
2408 break;
2409
2410 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2411 hci_cc_remote_name_req_cancel(hdev, skb);
2412 break;
2413
2414 case HCI_OP_ROLE_DISCOVERY:
2415 hci_cc_role_discovery(hdev, skb);
2416 break;
2417
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002418 case HCI_OP_READ_LINK_POLICY:
2419 hci_cc_read_link_policy(hdev, skb);
2420 break;
2421
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002422 case HCI_OP_WRITE_LINK_POLICY:
2423 hci_cc_write_link_policy(hdev, skb);
2424 break;
2425
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002426 case HCI_OP_READ_DEF_LINK_POLICY:
2427 hci_cc_read_def_link_policy(hdev, skb);
2428 break;
2429
2430 case HCI_OP_WRITE_DEF_LINK_POLICY:
2431 hci_cc_write_def_link_policy(hdev, skb);
2432 break;
2433
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002434 case HCI_OP_RESET:
2435 hci_cc_reset(hdev, skb);
2436 break;
2437
2438 case HCI_OP_WRITE_LOCAL_NAME:
2439 hci_cc_write_local_name(hdev, skb);
2440 break;
2441
2442 case HCI_OP_READ_LOCAL_NAME:
2443 hci_cc_read_local_name(hdev, skb);
2444 break;
2445
2446 case HCI_OP_WRITE_AUTH_ENABLE:
2447 hci_cc_write_auth_enable(hdev, skb);
2448 break;
2449
2450 case HCI_OP_WRITE_ENCRYPT_MODE:
2451 hci_cc_write_encrypt_mode(hdev, skb);
2452 break;
2453
2454 case HCI_OP_WRITE_SCAN_ENABLE:
2455 hci_cc_write_scan_enable(hdev, skb);
2456 break;
2457
2458 case HCI_OP_READ_CLASS_OF_DEV:
2459 hci_cc_read_class_of_dev(hdev, skb);
2460 break;
2461
2462 case HCI_OP_WRITE_CLASS_OF_DEV:
2463 hci_cc_write_class_of_dev(hdev, skb);
2464 break;
2465
2466 case HCI_OP_READ_VOICE_SETTING:
2467 hci_cc_read_voice_setting(hdev, skb);
2468 break;
2469
2470 case HCI_OP_WRITE_VOICE_SETTING:
2471 hci_cc_write_voice_setting(hdev, skb);
2472 break;
2473
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002474 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2475 hci_cc_read_num_supported_iac(hdev, skb);
2476 break;
2477
Marcel Holtmann333140b2008-07-14 20:13:48 +02002478 case HCI_OP_WRITE_SSP_MODE:
2479 hci_cc_write_ssp_mode(hdev, skb);
2480 break;
2481
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08002482 case HCI_OP_WRITE_SC_SUPPORT:
2483 hci_cc_write_sc_support(hdev, skb);
2484 break;
2485
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002486 case HCI_OP_READ_LOCAL_VERSION:
2487 hci_cc_read_local_version(hdev, skb);
2488 break;
2489
2490 case HCI_OP_READ_LOCAL_COMMANDS:
2491 hci_cc_read_local_commands(hdev, skb);
2492 break;
2493
2494 case HCI_OP_READ_LOCAL_FEATURES:
2495 hci_cc_read_local_features(hdev, skb);
2496 break;
2497
Andre Guedes971e3a42011-06-30 19:20:52 -03002498 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2499 hci_cc_read_local_ext_features(hdev, skb);
2500 break;
2501
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002502 case HCI_OP_READ_BUFFER_SIZE:
2503 hci_cc_read_buffer_size(hdev, skb);
2504 break;
2505
2506 case HCI_OP_READ_BD_ADDR:
2507 hci_cc_read_bd_addr(hdev, skb);
2508 break;
2509
Johan Hedbergf332ec62013-03-15 17:07:11 -05002510 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2511 hci_cc_read_page_scan_activity(hdev, skb);
2512 break;
2513
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002514 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2515 hci_cc_write_page_scan_activity(hdev, skb);
2516 break;
2517
Johan Hedbergf332ec62013-03-15 17:07:11 -05002518 case HCI_OP_READ_PAGE_SCAN_TYPE:
2519 hci_cc_read_page_scan_type(hdev, skb);
2520 break;
2521
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002522 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2523 hci_cc_write_page_scan_type(hdev, skb);
2524 break;
2525
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002526 case HCI_OP_READ_DATA_BLOCK_SIZE:
2527 hci_cc_read_data_block_size(hdev, skb);
2528 break;
2529
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002530 case HCI_OP_READ_FLOW_CONTROL_MODE:
2531 hci_cc_read_flow_control_mode(hdev, skb);
2532 break;
2533
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002534 case HCI_OP_READ_LOCAL_AMP_INFO:
2535 hci_cc_read_local_amp_info(hdev, skb);
2536 break;
2537
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002538 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2539 hci_cc_read_local_amp_assoc(hdev, skb);
2540 break;
2541
Johan Hedbergd5859e22011-01-25 01:19:58 +02002542 case HCI_OP_READ_INQ_RSP_TX_POWER:
2543 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2544 break;
2545
Johan Hedberg980e1a52011-01-22 06:10:07 +02002546 case HCI_OP_PIN_CODE_REPLY:
2547 hci_cc_pin_code_reply(hdev, skb);
2548 break;
2549
2550 case HCI_OP_PIN_CODE_NEG_REPLY:
2551 hci_cc_pin_code_neg_reply(hdev, skb);
2552 break;
2553
Szymon Jancc35938b2011-03-22 13:12:21 +01002554 case HCI_OP_READ_LOCAL_OOB_DATA:
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08002555 hci_cc_read_local_oob_data(hdev, skb);
2556 break;
2557
2558 case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
2559 hci_cc_read_local_oob_ext_data(hdev, skb);
Szymon Jancc35938b2011-03-22 13:12:21 +01002560 break;
2561
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002562 case HCI_OP_LE_READ_BUFFER_SIZE:
2563 hci_cc_le_read_buffer_size(hdev, skb);
2564 break;
2565
Johan Hedberg60e77322013-01-22 14:01:59 +02002566 case HCI_OP_LE_READ_LOCAL_FEATURES:
2567 hci_cc_le_read_local_features(hdev, skb);
2568 break;
2569
Johan Hedberg8fa19092012-10-19 20:57:49 +03002570 case HCI_OP_LE_READ_ADV_TX_POWER:
2571 hci_cc_le_read_adv_tx_power(hdev, skb);
2572 break;
2573
Johan Hedberga5c29682011-02-19 12:05:57 -03002574 case HCI_OP_USER_CONFIRM_REPLY:
2575 hci_cc_user_confirm_reply(hdev, skb);
2576 break;
2577
2578 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2579 hci_cc_user_confirm_neg_reply(hdev, skb);
2580 break;
2581
Brian Gix1143d452011-11-23 08:28:34 -08002582 case HCI_OP_USER_PASSKEY_REPLY:
2583 hci_cc_user_passkey_reply(hdev, skb);
2584 break;
2585
2586 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2587 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002588 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002589
Marcel Holtmann7a4cd512014-02-19 19:52:13 -08002590 case HCI_OP_LE_SET_RANDOM_ADDR:
2591 hci_cc_le_set_random_addr(hdev, skb);
2592 break;
2593
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002594 case HCI_OP_LE_SET_ADV_ENABLE:
2595 hci_cc_le_set_adv_enable(hdev, skb);
2596 break;
2597
Marcel Holtmann533553f2014-03-21 12:18:10 -07002598 case HCI_OP_LE_SET_SCAN_PARAM:
2599 hci_cc_le_set_scan_param(hdev, skb);
2600 break;
2601
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002602 case HCI_OP_LE_SET_SCAN_ENABLE:
2603 hci_cc_le_set_scan_enable(hdev, skb);
2604 break;
2605
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002606 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2607 hci_cc_le_read_white_list_size(hdev, skb);
2608 break;
2609
Marcel Holtmann0f36b582014-02-27 20:37:31 -08002610 case HCI_OP_LE_CLEAR_WHITE_LIST:
2611 hci_cc_le_clear_white_list(hdev, skb);
2612 break;
2613
2614 case HCI_OP_LE_ADD_TO_WHITE_LIST:
2615 hci_cc_le_add_to_white_list(hdev, skb);
2616 break;
2617
2618 case HCI_OP_LE_DEL_FROM_WHITE_LIST:
2619 hci_cc_le_del_from_white_list(hdev, skb);
2620 break;
2621
Johan Hedberg9b008c02013-01-22 14:02:01 +02002622 case HCI_OP_LE_READ_SUPPORTED_STATES:
2623 hci_cc_le_read_supported_states(hdev, skb);
2624 break;
2625
Andre Guedesf9b49302011-06-30 19:20:53 -03002626 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2627 hci_cc_write_le_host_supported(hdev, skb);
2628 break;
2629
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02002630 case HCI_OP_LE_SET_ADV_PARAM:
2631 hci_cc_set_adv_param(hdev, skb);
2632 break;
2633
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002634 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2635 hci_cc_write_remote_amp_assoc(hdev, skb);
2636 break;
2637
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002638 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002639 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002640 break;
2641 }
2642
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002643 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002644 del_timer(&hdev->cmd_timer);
2645
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002646 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002647
Szymon Jancdbccd792012-12-11 08:51:19 +01002648 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002649 atomic_set(&hdev->cmd_cnt, 1);
2650 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002651 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002652 }
2653}
2654
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002655static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002656{
2657 struct hci_ev_cmd_status *ev = (void *) skb->data;
2658 __u16 opcode;
2659
2660 skb_pull(skb, sizeof(*ev));
2661
2662 opcode = __le16_to_cpu(ev->opcode);
2663
2664 switch (opcode) {
2665 case HCI_OP_INQUIRY:
2666 hci_cs_inquiry(hdev, ev->status);
2667 break;
2668
2669 case HCI_OP_CREATE_CONN:
2670 hci_cs_create_conn(hdev, ev->status);
2671 break;
2672
2673 case HCI_OP_ADD_SCO:
2674 hci_cs_add_sco(hdev, ev->status);
2675 break;
2676
Marcel Holtmannf8558552008-07-14 20:13:49 +02002677 case HCI_OP_AUTH_REQUESTED:
2678 hci_cs_auth_requested(hdev, ev->status);
2679 break;
2680
2681 case HCI_OP_SET_CONN_ENCRYPT:
2682 hci_cs_set_conn_encrypt(hdev, ev->status);
2683 break;
2684
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002685 case HCI_OP_REMOTE_NAME_REQ:
2686 hci_cs_remote_name_req(hdev, ev->status);
2687 break;
2688
Marcel Holtmann769be972008-07-14 20:13:49 +02002689 case HCI_OP_READ_REMOTE_FEATURES:
2690 hci_cs_read_remote_features(hdev, ev->status);
2691 break;
2692
2693 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2694 hci_cs_read_remote_ext_features(hdev, ev->status);
2695 break;
2696
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002697 case HCI_OP_SETUP_SYNC_CONN:
2698 hci_cs_setup_sync_conn(hdev, ev->status);
2699 break;
2700
2701 case HCI_OP_SNIFF_MODE:
2702 hci_cs_sniff_mode(hdev, ev->status);
2703 break;
2704
2705 case HCI_OP_EXIT_SNIFF_MODE:
2706 hci_cs_exit_sniff_mode(hdev, ev->status);
2707 break;
2708
Johan Hedberg8962ee72011-01-20 12:40:27 +02002709 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002710 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002711 break;
2712
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002713 case HCI_OP_CREATE_PHY_LINK:
2714 hci_cs_create_phylink(hdev, ev->status);
2715 break;
2716
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002717 case HCI_OP_ACCEPT_PHY_LINK:
2718 hci_cs_accept_phylink(hdev, ev->status);
2719 break;
2720
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02002721 case HCI_OP_LE_CREATE_CONN:
2722 hci_cs_le_create_conn(hdev, ev->status);
2723 break;
2724
Johan Hedberg81d0c8a2014-03-24 14:39:04 +02002725 case HCI_OP_LE_START_ENC:
2726 hci_cs_le_start_enc(hdev, ev->status);
2727 break;
2728
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002729 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002730 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002731 break;
2732 }
2733
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002734 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002735 del_timer(&hdev->cmd_timer);
2736
Johan Hedberg02350a72013-04-03 21:50:29 +03002737 if (ev->status ||
2738 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2739 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002740
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002741 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002742 atomic_set(&hdev->cmd_cnt, 1);
2743 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002744 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002745 }
2746}
2747
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002748static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002749{
2750 struct hci_ev_role_change *ev = (void *) skb->data;
2751 struct hci_conn *conn;
2752
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002753 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002754
2755 hci_dev_lock(hdev);
2756
2757 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2758 if (conn) {
2759 if (!ev->status) {
2760 if (ev->role)
2761 conn->link_mode &= ~HCI_LM_MASTER;
2762 else
2763 conn->link_mode |= HCI_LM_MASTER;
2764 }
2765
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002766 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002767
2768 hci_role_switch_cfm(conn, ev->status, ev->role);
2769 }
2770
2771 hci_dev_unlock(hdev);
2772}
2773
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002774static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002775{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002776 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002777 int i;
2778
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002779 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2780 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2781 return;
2782 }
2783
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002784 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002785 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002786 BT_DBG("%s bad parameters", hdev->name);
2787 return;
2788 }
2789
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002790 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2791
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002792 for (i = 0; i < ev->num_hndl; i++) {
2793 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002794 struct hci_conn *conn;
2795 __u16 handle, count;
2796
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002797 handle = __le16_to_cpu(info->handle);
2798 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002799
2800 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002801 if (!conn)
2802 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002803
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002804 conn->sent -= count;
2805
2806 switch (conn->type) {
2807 case ACL_LINK:
2808 hdev->acl_cnt += count;
2809 if (hdev->acl_cnt > hdev->acl_pkts)
2810 hdev->acl_cnt = hdev->acl_pkts;
2811 break;
2812
2813 case LE_LINK:
2814 if (hdev->le_pkts) {
2815 hdev->le_cnt += count;
2816 if (hdev->le_cnt > hdev->le_pkts)
2817 hdev->le_cnt = hdev->le_pkts;
2818 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002819 hdev->acl_cnt += count;
2820 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821 hdev->acl_cnt = hdev->acl_pkts;
2822 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002823 break;
2824
2825 case SCO_LINK:
2826 hdev->sco_cnt += count;
2827 if (hdev->sco_cnt > hdev->sco_pkts)
2828 hdev->sco_cnt = hdev->sco_pkts;
2829 break;
2830
2831 default:
2832 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2833 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 }
2835 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002836
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002837 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838}
2839
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002840static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2841 __u16 handle)
2842{
2843 struct hci_chan *chan;
2844
2845 switch (hdev->dev_type) {
2846 case HCI_BREDR:
2847 return hci_conn_hash_lookup_handle(hdev, handle);
2848 case HCI_AMP:
2849 chan = hci_chan_lookup_handle(hdev, handle);
2850 if (chan)
2851 return chan->conn;
2852 break;
2853 default:
2854 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2855 break;
2856 }
2857
2858 return NULL;
2859}
2860
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002861static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002862{
2863 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2864 int i;
2865
2866 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2867 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2868 return;
2869 }
2870
2871 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002872 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002873 BT_DBG("%s bad parameters", hdev->name);
2874 return;
2875 }
2876
2877 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002878 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002879
2880 for (i = 0; i < ev->num_hndl; i++) {
2881 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002882 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002883 __u16 handle, block_count;
2884
2885 handle = __le16_to_cpu(info->handle);
2886 block_count = __le16_to_cpu(info->blocks);
2887
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002888 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002889 if (!conn)
2890 continue;
2891
2892 conn->sent -= block_count;
2893
2894 switch (conn->type) {
2895 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002896 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002897 hdev->block_cnt += block_count;
2898 if (hdev->block_cnt > hdev->num_blocks)
2899 hdev->block_cnt = hdev->num_blocks;
2900 break;
2901
2902 default:
2903 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2904 break;
2905 }
2906 }
2907
2908 queue_work(hdev->workqueue, &hdev->tx_work);
2909}
2910
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002911static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002912{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002913 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002914 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002915
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002916 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917
2918 hci_dev_lock(hdev);
2919
Marcel Holtmann04837f62006-07-03 10:02:33 +02002920 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2921 if (conn) {
2922 conn->mode = ev->mode;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002923
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002924 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2925 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002926 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002927 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002928 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002929 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002930 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002931
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002932 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002933 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002934 }
2935
2936 hci_dev_unlock(hdev);
2937}
2938
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002939static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002940{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002941 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2942 struct hci_conn *conn;
2943
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002944 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002945
2946 hci_dev_lock(hdev);
2947
2948 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002949 if (!conn)
2950 goto unlock;
2951
2952 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002953 hci_conn_hold(conn);
2954 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002955 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002956 }
2957
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002958 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002959 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002960 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002961 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002962 u8 secure;
2963
2964 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2965 secure = 1;
2966 else
2967 secure = 0;
2968
Johan Hedberg744cf192011-11-08 20:40:14 +02002969 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002970 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002971
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002972unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002973 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974}
2975
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002976static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002978 struct hci_ev_link_key_req *ev = (void *) skb->data;
2979 struct hci_cp_link_key_reply cp;
2980 struct hci_conn *conn;
2981 struct link_key *key;
2982
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002983 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002984
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002985 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002986 return;
2987
2988 hci_dev_lock(hdev);
2989
2990 key = hci_find_link_key(hdev, &ev->bdaddr);
2991 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002992 BT_DBG("%s link key not found for %pMR", hdev->name,
2993 &ev->bdaddr);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002994 goto not_found;
2995 }
2996
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002997 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2998 &ev->bdaddr);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002999
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003000 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003001 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02003002 BT_DBG("%s ignoring debug key", hdev->name);
3003 goto not_found;
3004 }
3005
3006 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02003007 if (conn) {
Marcel Holtmann66138ce2014-01-10 02:07:20 -08003008 if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
3009 key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003010 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02003011 BT_DBG("%s ignoring unauthenticated key", hdev->name);
3012 goto not_found;
3013 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02003014
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02003015 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003016 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003017 BT_DBG("%s ignoring key unauthenticated for high security",
3018 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02003019 goto not_found;
3020 }
3021
3022 conn->key_type = key->type;
3023 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02003024 }
3025
3026 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03003027 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02003028
3029 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
3030
3031 hci_dev_unlock(hdev);
3032
3033 return;
3034
3035not_found:
3036 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
3037 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_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003041{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003042 struct hci_ev_link_key_notify *ev = (void *) skb->data;
3043 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02003044 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003045
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003046 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003047
3048 hci_dev_lock(hdev);
3049
3050 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3051 if (conn) {
3052 hci_conn_hold(conn);
3053 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02003054 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02003055
3056 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
3057 conn->key_type = ev->key_type;
3058
David Herrmann76a68ba2013-04-06 20:28:37 +02003059 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003060 }
3061
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03003062 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07003063 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003064 ev->key_type, pin_len);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02003065
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003066 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003067}
3068
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003069static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02003070{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003071 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02003072 struct hci_conn *conn;
3073
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003074 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02003075
3076 hci_dev_lock(hdev);
3077
3078 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003079 if (conn && !ev->status) {
3080 struct inquiry_entry *ie;
3081
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003082 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3083 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003084 ie->data.clock_offset = ev->clock_offset;
3085 ie->timestamp = jiffies;
3086 }
3087 }
3088
3089 hci_dev_unlock(hdev);
3090}
3091
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003092static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02003093{
3094 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
3095 struct hci_conn *conn;
3096
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003097 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02003098
3099 hci_dev_lock(hdev);
3100
3101 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3102 if (conn && !ev->status)
3103 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
3104
3105 hci_dev_unlock(hdev);
3106}
3107
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003108static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003109{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003110 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003111 struct inquiry_entry *ie;
3112
3113 BT_DBG("%s", hdev->name);
3114
3115 hci_dev_lock(hdev);
3116
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003117 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3118 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003119 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
3120 ie->timestamp = jiffies;
3121 }
3122
3123 hci_dev_unlock(hdev);
3124}
3125
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003126static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
3127 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003128{
3129 struct inquiry_data data;
3130 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003131 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003132
3133 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3134
3135 if (!num_rsp)
3136 return;
3137
Andre Guedes1519cc12012-03-21 00:03:38 -03003138 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3139 return;
3140
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003141 hci_dev_lock(hdev);
3142
3143 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01003144 struct inquiry_info_with_rssi_and_pscan_mode *info;
3145 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003146
Johan Hedberge17acd42011-03-30 23:57:16 +03003147 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003148 bacpy(&data.bdaddr, &info->bdaddr);
3149 data.pscan_rep_mode = info->pscan_rep_mode;
3150 data.pscan_period_mode = info->pscan_period_mode;
3151 data.pscan_mode = info->pscan_mode;
3152 memcpy(data.dev_class, info->dev_class, 3);
3153 data.clock_offset = info->clock_offset;
3154 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003155 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003156
3157 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003158 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003159 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003160 info->dev_class, info->rssi,
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02003161 !name_known, ssp, NULL, 0, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003162 }
3163 } else {
3164 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
3165
Johan Hedberge17acd42011-03-30 23:57:16 +03003166 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003167 bacpy(&data.bdaddr, &info->bdaddr);
3168 data.pscan_rep_mode = info->pscan_rep_mode;
3169 data.pscan_period_mode = info->pscan_period_mode;
3170 data.pscan_mode = 0x00;
3171 memcpy(data.dev_class, info->dev_class, 3);
3172 data.clock_offset = info->clock_offset;
3173 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003174 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003175 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003176 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003177 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003178 info->dev_class, info->rssi,
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02003179 !name_known, ssp, NULL, 0, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003180 }
3181 }
3182
3183 hci_dev_unlock(hdev);
3184}
3185
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003186static void hci_remote_ext_features_evt(struct hci_dev *hdev,
3187 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003188{
Marcel Holtmann41a96212008-07-14 20:13:48 +02003189 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
3190 struct hci_conn *conn;
3191
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003192 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003193
Marcel Holtmann41a96212008-07-14 20:13:48 +02003194 hci_dev_lock(hdev);
3195
3196 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02003197 if (!conn)
3198 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003199
Johan Hedbergcad718e2013-04-17 15:00:51 +03003200 if (ev->page < HCI_MAX_PAGES)
3201 memcpy(conn->features[ev->page], ev->features, 8);
3202
Johan Hedbergccd556f2010-11-10 17:11:51 +02003203 if (!ev->status && ev->page == 0x01) {
3204 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003205
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003206 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3207 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003208 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02003209
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05303210 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02003211 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05303212 } else {
3213 /* It is mandatory by the Bluetooth specification that
3214 * Extended Inquiry Results are only used when Secure
3215 * Simple Pairing is enabled, but some devices violate
3216 * this.
3217 *
3218 * To make these devices work, the internal SSP
3219 * enabled flag needs to be cleared if the remote host
3220 * features do not indicate SSP support */
3221 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
3222 }
Marcel Holtmanneb9a8f32014-01-15 22:37:38 -08003223
3224 if (ev->features[0] & LMP_HOST_SC)
3225 set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003226 }
3227
Johan Hedbergccd556f2010-11-10 17:11:51 +02003228 if (conn->state != BT_CONFIG)
3229 goto unlock;
3230
Johan Hedberg671267b2012-05-12 16:11:50 -03003231 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02003232 struct hci_cp_remote_name_req cp;
3233 memset(&cp, 0, sizeof(cp));
3234 bacpy(&cp.bdaddr, &conn->dst);
3235 cp.pscan_rep_mode = 0x02;
3236 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02003237 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3238 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003239 conn->dst_type, 0, NULL, 0,
3240 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02003241
Johan Hedberg127178d2010-11-18 22:22:29 +02003242 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02003243 conn->state = BT_CONNECTED;
3244 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003245 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02003246 }
3247
3248unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02003249 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003250}
3251
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003252static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
3253 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003254{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003255 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
3256 struct hci_conn *conn;
3257
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003258 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003259
3260 hci_dev_lock(hdev);
3261
3262 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02003263 if (!conn) {
3264 if (ev->link_type == ESCO_LINK)
3265 goto unlock;
3266
3267 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
3268 if (!conn)
3269 goto unlock;
3270
3271 conn->type = SCO_LINK;
3272 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003273
Marcel Holtmann732547f2009-04-19 19:14:14 +02003274 switch (ev->status) {
3275 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003276 conn->handle = __le16_to_cpu(ev->handle);
3277 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02003278
3279 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02003280 break;
3281
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02003282 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05003283 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003284 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08003285 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003286 case 0x1f: /* Unspecified error */
Andrew Earl27539bc2014-03-10 10:31:04 +00003287 case 0x20: /* Unsupported LMP Parameter value */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003288 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02003289 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
3290 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003291 if (hci_setup_sync(conn, conn->link->handle))
3292 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003293 }
3294 /* fall through */
3295
3296 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003297 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003298 break;
3299 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003300
3301 hci_proto_connect_cfm(conn, ev->status);
3302 if (ev->status)
3303 hci_conn_del(conn);
3304
3305unlock:
3306 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003307}
3308
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07003309static inline size_t eir_get_length(u8 *eir, size_t eir_len)
3310{
3311 size_t parsed = 0;
3312
3313 while (parsed < eir_len) {
3314 u8 field_len = eir[0];
3315
3316 if (field_len == 0)
3317 return parsed;
3318
3319 parsed += field_len + 1;
3320 eir += field_len + 1;
3321 }
3322
3323 return eir_len;
3324}
3325
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003326static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3327 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003328{
3329 struct inquiry_data data;
3330 struct extended_inquiry_info *info = (void *) (skb->data + 1);
3331 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303332 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003333
3334 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3335
3336 if (!num_rsp)
3337 return;
3338
Andre Guedes1519cc12012-03-21 00:03:38 -03003339 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3340 return;
3341
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003342 hci_dev_lock(hdev);
3343
Johan Hedberge17acd42011-03-30 23:57:16 +03003344 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003345 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003346
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003347 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003348 data.pscan_rep_mode = info->pscan_rep_mode;
3349 data.pscan_period_mode = info->pscan_period_mode;
3350 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003351 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003352 data.clock_offset = info->clock_offset;
3353 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003354 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003355
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003356 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003357 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003358 sizeof(info->data),
3359 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003360 else
3361 name_known = true;
3362
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003363 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003364 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303365 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003366 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003367 info->dev_class, info->rssi, !name_known,
Johan Hedberg5d2e9fa2014-03-25 10:30:47 +02003368 ssp, info->data, eir_len, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003369 }
3370
3371 hci_dev_unlock(hdev);
3372}
3373
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003374static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3375 struct sk_buff *skb)
3376{
3377 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3378 struct hci_conn *conn;
3379
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003380 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003381 __le16_to_cpu(ev->handle));
3382
3383 hci_dev_lock(hdev);
3384
3385 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3386 if (!conn)
3387 goto unlock;
3388
3389 if (!ev->status)
3390 conn->sec_level = conn->pending_sec_level;
3391
3392 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3393
3394 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003395 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003396 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003397 goto unlock;
3398 }
3399
3400 if (conn->state == BT_CONFIG) {
3401 if (!ev->status)
3402 conn->state = BT_CONNECTED;
3403
3404 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003405 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003406 } else {
3407 hci_auth_cfm(conn, ev->status);
3408
3409 hci_conn_hold(conn);
3410 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003411 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003412 }
3413
3414unlock:
3415 hci_dev_unlock(hdev);
3416}
3417
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003418static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003419{
3420 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003421 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3422 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003423 /* If both remote and local IO capabilities allow MITM
3424 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003425 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3426 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3427 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003428 else
Mikel Astizacabae92013-06-28 10:56:28 +02003429 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003430 }
3431
3432 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003433 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3434 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003435 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003436
3437 return conn->auth_type;
3438}
3439
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003440static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003441{
3442 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3443 struct hci_conn *conn;
3444
3445 BT_DBG("%s", hdev->name);
3446
3447 hci_dev_lock(hdev);
3448
3449 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003450 if (!conn)
3451 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003452
Johan Hedberg03b555e2011-01-04 15:40:05 +02003453 hci_conn_hold(conn);
3454
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003455 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003456 goto unlock;
3457
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003458 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003459 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003460 struct hci_cp_io_capability_reply cp;
3461
3462 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303463 /* Change the IO capability from KeyboardDisplay
3464 * to DisplayYesNo as it is not supported by BT spec. */
3465 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003466 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003467 conn->auth_type = hci_get_auth_req(conn);
3468 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003469
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003470 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3471 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003472 cp.oob_data = 0x01;
3473 else
3474 cp.oob_data = 0x00;
3475
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003476 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003477 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003478 } else {
3479 struct hci_cp_io_capability_neg_reply cp;
3480
3481 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003482 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003483
3484 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003485 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003486 }
3487
3488unlock:
3489 hci_dev_unlock(hdev);
3490}
3491
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003492static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003493{
3494 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3495 struct hci_conn *conn;
3496
3497 BT_DBG("%s", hdev->name);
3498
3499 hci_dev_lock(hdev);
3500
3501 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3502 if (!conn)
3503 goto unlock;
3504
Johan Hedberg03b555e2011-01-04 15:40:05 +02003505 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003506 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003507 if (ev->oob_data)
3508 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003509
3510unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003511 hci_dev_unlock(hdev);
3512}
3513
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003514static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3515 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003516{
3517 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003518 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003519 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003520
3521 BT_DBG("%s", hdev->name);
3522
3523 hci_dev_lock(hdev);
3524
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003525 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003526 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003527
Johan Hedberg7a828902011-04-28 11:28:53 -07003528 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3529 if (!conn)
3530 goto unlock;
3531
3532 loc_mitm = (conn->auth_type & 0x01);
3533 rem_mitm = (conn->remote_auth & 0x01);
3534
3535 /* If we require MITM but the remote device can't provide that
3536 * (it has NoInputNoOutput) then reject the confirmation
3537 * request. The only exception is when we're dedicated bonding
3538 * initiators (connect_cfm_cb set) since then we always have the MITM
3539 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003540 if (!conn->connect_cfm_cb && loc_mitm &&
3541 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003542 BT_DBG("Rejecting request: remote device can't provide MITM");
3543 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003544 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003545 goto unlock;
3546 }
3547
3548 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003549 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3550 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003551
3552 /* If we're not the initiators request authorization to
3553 * proceed from user space (mgmt_user_confirm with
3554 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003555 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003556 BT_DBG("Confirming auto-accept as acceptor");
3557 confirm_hint = 1;
3558 goto confirm;
3559 }
3560
Johan Hedberg9f616562011-04-28 11:28:54 -07003561 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003562 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003563
3564 if (hdev->auto_accept_delay > 0) {
3565 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
Johan Hedberg7bc18d92013-10-16 18:11:39 +03003566 queue_delayed_work(conn->hdev->workqueue,
3567 &conn->auto_accept_work, delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003568 goto unlock;
3569 }
3570
Johan Hedberg7a828902011-04-28 11:28:53 -07003571 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003572 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003573 goto unlock;
3574 }
3575
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003576confirm:
Johan Hedberg39adbff2014-03-20 08:18:14 +02003577 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0,
3578 le32_to_cpu(ev->passkey), confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003579
3580unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003581 hci_dev_unlock(hdev);
3582}
3583
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003584static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3585 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003586{
3587 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3588
3589 BT_DBG("%s", hdev->name);
3590
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003591 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003592 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003593}
3594
Johan Hedberg92a25252012-09-06 18:39:26 +03003595static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3596 struct sk_buff *skb)
3597{
3598 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3599 struct hci_conn *conn;
3600
3601 BT_DBG("%s", hdev->name);
3602
3603 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3604 if (!conn)
3605 return;
3606
3607 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3608 conn->passkey_entered = 0;
3609
3610 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3611 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3612 conn->dst_type, conn->passkey_notify,
3613 conn->passkey_entered);
3614}
3615
3616static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3617{
3618 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3619 struct hci_conn *conn;
3620
3621 BT_DBG("%s", hdev->name);
3622
3623 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3624 if (!conn)
3625 return;
3626
3627 switch (ev->type) {
3628 case HCI_KEYPRESS_STARTED:
3629 conn->passkey_entered = 0;
3630 return;
3631
3632 case HCI_KEYPRESS_ENTERED:
3633 conn->passkey_entered++;
3634 break;
3635
3636 case HCI_KEYPRESS_ERASED:
3637 conn->passkey_entered--;
3638 break;
3639
3640 case HCI_KEYPRESS_CLEARED:
3641 conn->passkey_entered = 0;
3642 break;
3643
3644 case HCI_KEYPRESS_COMPLETED:
3645 return;
3646 }
3647
3648 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3649 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3650 conn->dst_type, conn->passkey_notify,
3651 conn->passkey_entered);
3652}
3653
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003654static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3655 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003656{
3657 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3658 struct hci_conn *conn;
3659
3660 BT_DBG("%s", hdev->name);
3661
3662 hci_dev_lock(hdev);
3663
3664 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003665 if (!conn)
3666 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003667
Johan Hedberg2a611692011-02-19 12:06:00 -03003668 /* To avoid duplicate auth_failed events to user space we check
3669 * the HCI_CONN_AUTH_PEND flag which will be set if we
3670 * initiated the authentication. A traditional auth_complete
3671 * event gets always produced as initiator and is also mapped to
3672 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003673 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003674 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003675 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003676
David Herrmann76a68ba2013-04-06 20:28:37 +02003677 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003678
3679unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003680 hci_dev_unlock(hdev);
3681}
3682
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003683static void hci_remote_host_features_evt(struct hci_dev *hdev,
3684 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003685{
3686 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3687 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003688 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003689
3690 BT_DBG("%s", hdev->name);
3691
3692 hci_dev_lock(hdev);
3693
Johan Hedbergcad718e2013-04-17 15:00:51 +03003694 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3695 if (conn)
3696 memcpy(conn->features[1], ev->features, 8);
3697
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003698 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3699 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003700 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003701
3702 hci_dev_unlock(hdev);
3703}
3704
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003705static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3706 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003707{
3708 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3709 struct oob_data *data;
3710
3711 BT_DBG("%s", hdev->name);
3712
3713 hci_dev_lock(hdev);
3714
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003715 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003716 goto unlock;
3717
Szymon Janc2763eda2011-03-22 13:12:22 +01003718 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3719 if (data) {
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003720 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
3721 struct hci_cp_remote_oob_ext_data_reply cp;
Szymon Janc2763eda2011-03-22 13:12:22 +01003722
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003723 bacpy(&cp.bdaddr, &ev->bdaddr);
3724 memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
3725 memcpy(cp.randomizer192, data->randomizer192,
3726 sizeof(cp.randomizer192));
3727 memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
3728 memcpy(cp.randomizer256, data->randomizer256,
3729 sizeof(cp.randomizer256));
Szymon Janc2763eda2011-03-22 13:12:22 +01003730
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003731 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
3732 sizeof(cp), &cp);
3733 } else {
3734 struct hci_cp_remote_oob_data_reply cp;
3735
3736 bacpy(&cp.bdaddr, &ev->bdaddr);
3737 memcpy(cp.hash, data->hash192, sizeof(cp.hash));
3738 memcpy(cp.randomizer, data->randomizer192,
3739 sizeof(cp.randomizer));
3740
3741 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
3742 sizeof(cp), &cp);
3743 }
Szymon Janc2763eda2011-03-22 13:12:22 +01003744 } else {
3745 struct hci_cp_remote_oob_data_neg_reply cp;
3746
3747 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003748 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
3749 sizeof(cp), &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003750 }
3751
Szymon Jance1ba1f12011-04-06 13:01:59 +02003752unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003753 hci_dev_unlock(hdev);
3754}
3755
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003756static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3757 struct sk_buff *skb)
3758{
3759 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3760 struct hci_conn *hcon, *bredr_hcon;
3761
3762 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3763 ev->status);
3764
3765 hci_dev_lock(hdev);
3766
3767 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3768 if (!hcon) {
3769 hci_dev_unlock(hdev);
3770 return;
3771 }
3772
3773 if (ev->status) {
3774 hci_conn_del(hcon);
3775 hci_dev_unlock(hdev);
3776 return;
3777 }
3778
3779 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3780
3781 hcon->state = BT_CONNECTED;
3782 bacpy(&hcon->dst, &bredr_hcon->dst);
3783
3784 hci_conn_hold(hcon);
3785 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003786 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003787
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003788 hci_conn_add_sysfs(hcon);
3789
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003790 amp_physical_cfm(bredr_hcon, hcon);
3791
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003792 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003793}
3794
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003795static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3796{
3797 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3798 struct hci_conn *hcon;
3799 struct hci_chan *hchan;
3800 struct amp_mgr *mgr;
3801
3802 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3803 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3804 ev->status);
3805
3806 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3807 if (!hcon)
3808 return;
3809
3810 /* Create AMP hchan */
3811 hchan = hci_chan_create(hcon);
3812 if (!hchan)
3813 return;
3814
3815 hchan->handle = le16_to_cpu(ev->handle);
3816
3817 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3818
3819 mgr = hcon->amp_mgr;
3820 if (mgr && mgr->bredr_chan) {
3821 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3822
3823 l2cap_chan_lock(bredr_chan);
3824
3825 bredr_chan->conn->mtu = hdev->block_mtu;
3826 l2cap_logical_cfm(bredr_chan, hchan, 0);
3827 hci_conn_hold(hcon);
3828
3829 l2cap_chan_unlock(bredr_chan);
3830 }
3831}
3832
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003833static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3834 struct sk_buff *skb)
3835{
3836 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3837 struct hci_chan *hchan;
3838
3839 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3840 le16_to_cpu(ev->handle), ev->status);
3841
3842 if (ev->status)
3843 return;
3844
3845 hci_dev_lock(hdev);
3846
3847 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3848 if (!hchan)
3849 goto unlock;
3850
3851 amp_destroy_logical_link(hchan, ev->reason);
3852
3853unlock:
3854 hci_dev_unlock(hdev);
3855}
3856
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003857static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3858 struct sk_buff *skb)
3859{
3860 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3861 struct hci_conn *hcon;
3862
3863 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3864
3865 if (ev->status)
3866 return;
3867
3868 hci_dev_lock(hdev);
3869
3870 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3871 if (hcon) {
3872 hcon->state = BT_CLOSED;
3873 hci_conn_del(hcon);
3874 }
3875
3876 hci_dev_unlock(hdev);
3877}
3878
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003879static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003880{
3881 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3882 struct hci_conn *conn;
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003883 struct smp_irk *irk;
Ville Tervofcd89c02011-02-10 22:38:47 -03003884
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003885 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003886
3887 hci_dev_lock(hdev);
3888
Andre Guedesb47a09b2012-07-27 15:10:15 -03003889 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003890 if (!conn) {
3891 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3892 if (!conn) {
3893 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003894 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003895 }
Andre Guedes29b79882011-05-31 14:20:54 -03003896
3897 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003898
3899 if (ev->role == LE_CONN_ROLE_MASTER) {
3900 conn->out = true;
3901 conn->link_mode |= HCI_LM_MASTER;
3902 }
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02003903
3904 /* If we didn't have a hci_conn object previously
3905 * but we're in master role this must be something
3906 * initiated using a white list. Since white list based
3907 * connections are not "first class citizens" we don't
3908 * have full tracking of them. Therefore, we go ahead
3909 * with a "best effort" approach of determining the
3910 * initiator address based on the HCI_PRIVACY flag.
3911 */
3912 if (conn->out) {
3913 conn->resp_addr_type = ev->bdaddr_type;
3914 bacpy(&conn->resp_addr, &ev->bdaddr);
3915 if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
3916 conn->init_addr_type = ADDR_LE_DEV_RANDOM;
3917 bacpy(&conn->init_addr, &hdev->rpa);
3918 } else {
3919 hci_copy_identity_address(hdev,
3920 &conn->init_addr,
3921 &conn->init_addr_type);
3922 }
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02003923 }
Johan Hedberg9489eca2014-02-28 17:45:46 +02003924 } else {
3925 cancel_delayed_work(&conn->le_conn_timeout);
Ville Tervob62f3282011-02-10 22:38:50 -03003926 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003927
Johan Hedberg80c24ab2014-03-24 20:21:51 +02003928 if (!conn->out) {
3929 /* Set the responder (our side) address type based on
3930 * the advertising address type.
3931 */
3932 conn->resp_addr_type = hdev->adv_addr_type;
3933 if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM)
3934 bacpy(&conn->resp_addr, &hdev->random_addr);
3935 else
3936 bacpy(&conn->resp_addr, &hdev->bdaddr);
3937
3938 conn->init_addr_type = ev->bdaddr_type;
3939 bacpy(&conn->init_addr, &ev->bdaddr);
3940 }
3941
Marcel Holtmannedb4b462014-02-18 15:13:43 -08003942 /* Lookup the identity address from the stored connection
3943 * address and address type.
3944 *
3945 * When establishing connections to an identity address, the
3946 * connection procedure will store the resolvable random
3947 * address first. Now if it can be converted back into the
3948 * identity address, start using the identity address from
3949 * now on.
3950 */
3951 irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003952 if (irk) {
3953 bacpy(&conn->dst, &irk->bdaddr);
3954 conn->dst_type = irk->addr_type;
3955 }
3956
Andre Guedescd17dec2012-07-27 15:10:16 -03003957 if (ev->status) {
Andre Guedes06c053f2014-02-26 20:21:41 -03003958 hci_le_conn_failed(conn, ev->status);
Andre Guedescd17dec2012-07-27 15:10:16 -03003959 goto unlock;
3960 }
3961
Johan Hedbergb644ba32012-01-17 21:48:47 +02003962 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Marcel Holtmann01fdb0f2014-02-18 14:22:19 -08003963 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003964 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003965
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003966 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003967 conn->handle = __le16_to_cpu(ev->handle);
3968 conn->state = BT_CONNECTED;
3969
Jukka Rissanen18722c22013-12-11 17:05:37 +02003970 if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
3971 set_bit(HCI_CONN_6LOWPAN, &conn->flags);
3972
Ville Tervofcd89c02011-02-10 22:38:47 -03003973 hci_conn_add_sysfs(conn);
3974
3975 hci_proto_connect_cfm(conn, ev->status);
3976
Andre Guedesa4790db2014-02-26 20:21:47 -03003977 hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type);
3978
Ville Tervofcd89c02011-02-10 22:38:47 -03003979unlock:
3980 hci_dev_unlock(hdev);
3981}
3982
Andre Guedesa4790db2014-02-26 20:21:47 -03003983/* This function requires the caller holds hdev->lock */
3984static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
3985 u8 addr_type)
3986{
3987 struct hci_conn *conn;
Andre Guedes5b906a82014-02-26 20:21:53 -03003988 struct smp_irk *irk;
3989
3990 /* If this is a resolvable address, we should resolve it and then
3991 * update address and address type variables.
3992 */
3993 irk = hci_get_irk(hdev, addr, addr_type);
3994 if (irk) {
3995 addr = &irk->bdaddr;
3996 addr_type = irk->addr_type;
3997 }
Andre Guedesa4790db2014-02-26 20:21:47 -03003998
3999 if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
4000 return;
4001
4002 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
4003 HCI_AT_NO_BONDING);
4004 if (!IS_ERR(conn))
4005 return;
4006
4007 switch (PTR_ERR(conn)) {
4008 case -EBUSY:
4009 /* If hci_connect() returns -EBUSY it means there is already
4010 * an LE connection attempt going on. Since controllers don't
4011 * support more than one connection attempt at the time, we
4012 * don't consider this an error case.
4013 */
4014 break;
4015 default:
4016 BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
4017 }
4018}
4019
Johan Hedberg4af605d2014-03-24 10:48:00 +02004020static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
4021 u8 bdaddr_type, s8 rssi, u8 *data, u8 len)
4022{
Johan Hedbergb9a63282014-03-25 10:51:52 +02004023 struct discovery_state *d = &hdev->discovery;
Johan Hedberg474ee062014-03-25 14:34:59 +02004024 bool match;
Johan Hedbergb9a63282014-03-25 10:51:52 +02004025
Johan Hedbergca5c4be2014-03-25 10:30:46 +02004026 /* Passive scanning shouldn't trigger any device found events */
4027 if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
4028 if (type == LE_ADV_IND || type == LE_ADV_DIRECT_IND)
4029 check_pending_le_conn(hdev, bdaddr, bdaddr_type);
4030 return;
4031 }
Johan Hedberg4af605d2014-03-24 10:48:00 +02004032
Johan Hedbergb9a63282014-03-25 10:51:52 +02004033 /* If there's nothing pending either store the data from this
4034 * event or send an immediate device found event if the data
4035 * should not be stored for later.
4036 */
4037 if (!has_pending_adv_report(hdev)) {
4038 /* If the report will trigger a SCAN_REQ store it for
4039 * later merging.
4040 */
4041 if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
4042 store_pending_adv_report(hdev, bdaddr, bdaddr_type,
4043 data, len);
4044 return;
4045 }
4046
4047 mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
4048 rssi, 0, 1, data, len, NULL, 0);
4049 return;
4050 }
4051
Johan Hedberg474ee062014-03-25 14:34:59 +02004052 /* Check if the pending report is for the same device as the new one */
4053 match = (!bacmp(bdaddr, &d->last_adv_addr) &&
4054 bdaddr_type == d->last_adv_addr_type);
4055
Johan Hedbergb9a63282014-03-25 10:51:52 +02004056 /* If the pending data doesn't match this report or this isn't a
4057 * scan response (e.g. we got a duplicate ADV_IND) then force
4058 * sending of the pending data.
4059 */
Johan Hedberg474ee062014-03-25 14:34:59 +02004060 if (type != LE_ADV_SCAN_RSP || !match) {
4061 /* Send out whatever is in the cache, but skip duplicates */
4062 if (!match)
4063 mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
4064 d->last_adv_addr_type, NULL, 0,
4065 0, 1, d->last_adv_data,
4066 d->last_adv_data_len, NULL, 0);
Johan Hedbergb9a63282014-03-25 10:51:52 +02004067
4068 /* If the new report will trigger a SCAN_REQ store it for
4069 * later merging.
4070 */
4071 if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
4072 store_pending_adv_report(hdev, bdaddr, bdaddr_type,
4073 data, len);
4074 return;
4075 }
4076
4077 /* The advertising reports cannot be merged, so clear
4078 * the pending report and send out a device found event.
4079 */
4080 clear_pending_adv_report(hdev);
4081 mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
4082 d->last_adv_addr_type, NULL, rssi, 0, 1,
4083 data, len, NULL, 0);
4084 return;
4085 }
4086
4087 /* If we get here we've got a pending ADV_IND or ADV_SCAN_IND and
4088 * the new event is a SCAN_RSP. We can therefore proceed with
4089 * sending a merged device found event.
4090 */
4091 mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK,
4092 d->last_adv_addr_type, NULL, rssi, 0, 1, data, len,
4093 d->last_adv_data, d->last_adv_data_len);
4094 clear_pending_adv_report(hdev);
Johan Hedberg4af605d2014-03-24 10:48:00 +02004095}
4096
Gustavo Padovan6039aa732012-05-23 04:04:18 -03004097static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03004098{
Andre Guedese95beb42011-09-26 20:48:35 -03004099 u8 num_reports = skb->data[0];
4100 void *ptr = &skb->data[1];
Andre Guedes9aa04c92011-05-26 16:23:51 -03004101
Andre Guedesa4790db2014-02-26 20:21:47 -03004102 hci_dev_lock(hdev);
4103
Andre Guedese95beb42011-09-26 20:48:35 -03004104 while (num_reports--) {
4105 struct hci_ev_le_advertising_info *ev = ptr;
Johan Hedberg4af605d2014-03-24 10:48:00 +02004106 s8 rssi;
Andre Guedesa4790db2014-02-26 20:21:47 -03004107
Andre Guedes3c9e9192012-01-10 18:20:50 -03004108 rssi = ev->data[ev->length];
Johan Hedberg4af605d2014-03-24 10:48:00 +02004109 process_adv_report(hdev, ev->evt_type, &ev->bdaddr,
4110 ev->bdaddr_type, rssi, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03004111
Andre Guedese95beb42011-09-26 20:48:35 -03004112 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03004113 }
Andre Guedesa4790db2014-02-26 20:21:47 -03004114
4115 hci_dev_unlock(hdev);
Andre Guedes9aa04c92011-05-26 16:23:51 -03004116}
4117
Gustavo Padovan6039aa732012-05-23 04:04:18 -03004118static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004119{
4120 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
4121 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004122 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004123 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03004124 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004125
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03004126 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004127
4128 hci_dev_lock(hdev);
4129
4130 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004131 if (conn == NULL)
4132 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004133
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08004134 ltk = hci_find_ltk(hdev, ev->ediv, ev->rand, conn->out);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004135 if (ltk == NULL)
4136 goto not_found;
4137
4138 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004139 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03004140
4141 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03004142 conn->pending_sec_level = BT_SECURITY_HIGH;
4143 else
4144 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004145
Andre Guedes89cbb4d2013-07-31 16:25:29 -03004146 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004147
4148 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
4149
Claudio Takahasi5981a882013-07-25 16:34:24 -03004150 /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
4151 * temporary key used to encrypt a connection following
4152 * pairing. It is used during the Encrypted Session Setup to
4153 * distribute the keys. Later, security can be re-established
4154 * using a distributed LTK.
4155 */
4156 if (ltk->type == HCI_SMP_STK_SLAVE) {
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03004157 list_del(&ltk->list);
4158 kfree(ltk);
4159 }
4160
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004161 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004162
4163 return;
4164
4165not_found:
4166 neg.handle = ev->handle;
4167 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
4168 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004169}
4170
Gustavo Padovan6039aa732012-05-23 04:04:18 -03004171static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03004172{
4173 struct hci_ev_le_meta *le_ev = (void *) skb->data;
4174
4175 skb_pull(skb, sizeof(*le_ev));
4176
4177 switch (le_ev->subevent) {
4178 case HCI_EV_LE_CONN_COMPLETE:
4179 hci_le_conn_complete_evt(hdev, skb);
4180 break;
4181
Andre Guedes9aa04c92011-05-26 16:23:51 -03004182 case HCI_EV_LE_ADVERTISING_REPORT:
4183 hci_le_adv_report_evt(hdev, skb);
4184 break;
4185
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004186 case HCI_EV_LE_LTK_REQ:
4187 hci_le_ltk_request_evt(hdev, skb);
4188 break;
4189
Ville Tervofcd89c02011-02-10 22:38:47 -03004190 default:
4191 break;
4192 }
4193}
4194
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004195static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
4196{
4197 struct hci_ev_channel_selected *ev = (void *) skb->data;
4198 struct hci_conn *hcon;
4199
4200 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
4201
4202 skb_pull(skb, sizeof(*ev));
4203
4204 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
4205 if (!hcon)
4206 return;
4207
4208 amp_read_loc_assoc_final_data(hdev, hcon);
4209}
4210
Linus Torvalds1da177e2005-04-16 15:20:36 -07004211void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
4212{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004213 struct hci_event_hdr *hdr = (void *) skb->data;
4214 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004215
Johan Hedbergb6ddb632013-04-02 13:34:31 +03004216 hci_dev_lock(hdev);
4217
4218 /* Received events are (currently) only needed when a request is
4219 * ongoing so avoid unnecessary memory allocation.
4220 */
4221 if (hdev->req_status == HCI_REQ_PEND) {
4222 kfree_skb(hdev->recv_evt);
4223 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
4224 }
4225
4226 hci_dev_unlock(hdev);
4227
Linus Torvalds1da177e2005-04-16 15:20:36 -07004228 skb_pull(skb, HCI_EVENT_HDR_SIZE);
4229
Johan Hedberg02350a72013-04-03 21:50:29 +03004230 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02004231 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
4232 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03004233
4234 hci_req_cmd_complete(hdev, opcode, 0);
4235 }
4236
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004237 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004238 case HCI_EV_INQUIRY_COMPLETE:
4239 hci_inquiry_complete_evt(hdev, skb);
4240 break;
4241
4242 case HCI_EV_INQUIRY_RESULT:
4243 hci_inquiry_result_evt(hdev, skb);
4244 break;
4245
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004246 case HCI_EV_CONN_COMPLETE:
4247 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02004248 break;
4249
Linus Torvalds1da177e2005-04-16 15:20:36 -07004250 case HCI_EV_CONN_REQUEST:
4251 hci_conn_request_evt(hdev, skb);
4252 break;
4253
Linus Torvalds1da177e2005-04-16 15:20:36 -07004254 case HCI_EV_DISCONN_COMPLETE:
4255 hci_disconn_complete_evt(hdev, skb);
4256 break;
4257
Linus Torvalds1da177e2005-04-16 15:20:36 -07004258 case HCI_EV_AUTH_COMPLETE:
4259 hci_auth_complete_evt(hdev, skb);
4260 break;
4261
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004262 case HCI_EV_REMOTE_NAME:
4263 hci_remote_name_evt(hdev, skb);
4264 break;
4265
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266 case HCI_EV_ENCRYPT_CHANGE:
4267 hci_encrypt_change_evt(hdev, skb);
4268 break;
4269
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004270 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
4271 hci_change_link_key_complete_evt(hdev, skb);
4272 break;
4273
4274 case HCI_EV_REMOTE_FEATURES:
4275 hci_remote_features_evt(hdev, skb);
4276 break;
4277
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004278 case HCI_EV_CMD_COMPLETE:
4279 hci_cmd_complete_evt(hdev, skb);
4280 break;
4281
4282 case HCI_EV_CMD_STATUS:
4283 hci_cmd_status_evt(hdev, skb);
4284 break;
4285
4286 case HCI_EV_ROLE_CHANGE:
4287 hci_role_change_evt(hdev, skb);
4288 break;
4289
4290 case HCI_EV_NUM_COMP_PKTS:
4291 hci_num_comp_pkts_evt(hdev, skb);
4292 break;
4293
4294 case HCI_EV_MODE_CHANGE:
4295 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004296 break;
4297
4298 case HCI_EV_PIN_CODE_REQ:
4299 hci_pin_code_request_evt(hdev, skb);
4300 break;
4301
4302 case HCI_EV_LINK_KEY_REQ:
4303 hci_link_key_request_evt(hdev, skb);
4304 break;
4305
4306 case HCI_EV_LINK_KEY_NOTIFY:
4307 hci_link_key_notify_evt(hdev, skb);
4308 break;
4309
4310 case HCI_EV_CLOCK_OFFSET:
4311 hci_clock_offset_evt(hdev, skb);
4312 break;
4313
Marcel Holtmanna8746412008-07-14 20:13:46 +02004314 case HCI_EV_PKT_TYPE_CHANGE:
4315 hci_pkt_type_change_evt(hdev, skb);
4316 break;
4317
Marcel Holtmann85a1e932005-08-09 20:28:02 -07004318 case HCI_EV_PSCAN_REP_MODE:
4319 hci_pscan_rep_mode_evt(hdev, skb);
4320 break;
4321
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004322 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
4323 hci_inquiry_result_with_rssi_evt(hdev, skb);
4324 break;
4325
4326 case HCI_EV_REMOTE_EXT_FEATURES:
4327 hci_remote_ext_features_evt(hdev, skb);
4328 break;
4329
4330 case HCI_EV_SYNC_CONN_COMPLETE:
4331 hci_sync_conn_complete_evt(hdev, skb);
4332 break;
4333
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004334 case HCI_EV_EXTENDED_INQUIRY_RESULT:
4335 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004336 break;
4337
Johan Hedberg1c2e0042012-06-08 23:31:13 +08004338 case HCI_EV_KEY_REFRESH_COMPLETE:
4339 hci_key_refresh_complete_evt(hdev, skb);
4340 break;
4341
Marcel Holtmann04936842008-07-14 20:13:48 +02004342 case HCI_EV_IO_CAPA_REQUEST:
4343 hci_io_capa_request_evt(hdev, skb);
4344 break;
4345
Johan Hedberg03b555e2011-01-04 15:40:05 +02004346 case HCI_EV_IO_CAPA_REPLY:
4347 hci_io_capa_reply_evt(hdev, skb);
4348 break;
4349
Johan Hedberga5c29682011-02-19 12:05:57 -03004350 case HCI_EV_USER_CONFIRM_REQUEST:
4351 hci_user_confirm_request_evt(hdev, skb);
4352 break;
4353
Brian Gix1143d452011-11-23 08:28:34 -08004354 case HCI_EV_USER_PASSKEY_REQUEST:
4355 hci_user_passkey_request_evt(hdev, skb);
4356 break;
4357
Johan Hedberg92a25252012-09-06 18:39:26 +03004358 case HCI_EV_USER_PASSKEY_NOTIFY:
4359 hci_user_passkey_notify_evt(hdev, skb);
4360 break;
4361
4362 case HCI_EV_KEYPRESS_NOTIFY:
4363 hci_keypress_notify_evt(hdev, skb);
4364 break;
4365
Marcel Holtmann04936842008-07-14 20:13:48 +02004366 case HCI_EV_SIMPLE_PAIR_COMPLETE:
4367 hci_simple_pair_complete_evt(hdev, skb);
4368 break;
4369
Marcel Holtmann41a96212008-07-14 20:13:48 +02004370 case HCI_EV_REMOTE_HOST_FEATURES:
4371 hci_remote_host_features_evt(hdev, skb);
4372 break;
4373
Ville Tervofcd89c02011-02-10 22:38:47 -03004374 case HCI_EV_LE_META:
4375 hci_le_meta_evt(hdev, skb);
4376 break;
4377
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004378 case HCI_EV_CHANNEL_SELECTED:
4379 hci_chan_selected_evt(hdev, skb);
4380 break;
4381
Szymon Janc2763eda2011-03-22 13:12:22 +01004382 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
4383 hci_remote_oob_data_request_evt(hdev, skb);
4384 break;
4385
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03004386 case HCI_EV_PHY_LINK_COMPLETE:
4387 hci_phy_link_complete_evt(hdev, skb);
4388 break;
4389
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004390 case HCI_EV_LOGICAL_LINK_COMPLETE:
4391 hci_loglink_complete_evt(hdev, skb);
4392 break;
4393
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02004394 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
4395 hci_disconn_loglink_complete_evt(hdev, skb);
4396 break;
4397
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02004398 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
4399 hci_disconn_phylink_complete_evt(hdev, skb);
4400 break;
4401
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02004402 case HCI_EV_NUM_COMP_BLOCKS:
4403 hci_num_comp_blocks_evt(hdev, skb);
4404 break;
4405
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004406 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03004407 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004408 break;
4409 }
4410
4411 kfree_skb(skb);
4412 hdev->stat.evt_rx++;
4413}