blob: 9ee081b9c06413197d75d61905207beb493ff65e [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
994 hci_dev_lock(hdev);
995
Johan Hedberg778b2352014-02-24 14:52:17 +0200996 if (!status)
997 mgmt_advertising(hdev, *sent);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100998
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500999 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01001000}
1001
Marcel Holtmann533553f2014-03-21 12:18:10 -07001002static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1003{
1004 struct hci_cp_le_set_scan_param *cp;
1005 __u8 status = *((__u8 *) skb->data);
1006
1007 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1008
1009 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM);
1010 if (!cp)
1011 return;
1012
1013 hci_dev_lock(hdev);
1014
1015 if (!status)
1016 hdev->le_scan_type = cp->type;
1017
1018 hci_dev_unlock(hdev);
1019}
1020
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001021static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001022 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001023{
1024 struct hci_cp_le_set_scan_enable *cp;
1025 __u8 status = *((__u8 *) skb->data);
1026
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001027 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001028
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001029 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1030 if (!cp)
1031 return;
1032
Andre Guedes3fd319b2013-04-30 15:29:36 -03001033 if (status)
1034 return;
1035
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001036 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -03001037 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -03001038 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001039 break;
1040
Andre Guedes76a388b2013-04-04 20:21:02 -03001041 case LE_SCAN_DISABLE:
Johan Hedberg317ac8c2014-02-28 20:26:12 +02001042 /* Cancel this timer so that we don't try to disable scanning
1043 * when it's already disabled.
1044 */
1045 cancel_delayed_work(&hdev->le_scan_disable);
1046
Andre Guedesd23264a2011-11-25 20:53:38 -03001047 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Johan Hedberg81ad6fd2014-02-28 20:26:13 +02001048 /* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
1049 * interrupted scanning due to a connect request. Mark
1050 * therefore discovery as stopped.
1051 */
1052 if (test_and_clear_bit(HCI_LE_SCAN_INTERRUPTED,
1053 &hdev->dev_flags))
1054 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001055 break;
1056
1057 default:
1058 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1059 break;
Andre Guedes35815082011-05-26 16:23:53 -03001060 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001061}
1062
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001063static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
1064 struct sk_buff *skb)
1065{
1066 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
1067
1068 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
1069
1070 if (!rp->status)
1071 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001072}
1073
Marcel Holtmann0f36b582014-02-27 20:37:31 -08001074static void hci_cc_le_clear_white_list(struct hci_dev *hdev,
1075 struct sk_buff *skb)
1076{
1077 __u8 status = *((__u8 *) skb->data);
1078
1079 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1080
1081 if (!status)
1082 hci_white_list_clear(hdev);
1083}
1084
1085static void hci_cc_le_add_to_white_list(struct hci_dev *hdev,
1086 struct sk_buff *skb)
1087{
1088 struct hci_cp_le_add_to_white_list *sent;
1089 __u8 status = *((__u8 *) skb->data);
1090
1091 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1092
1093 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST);
1094 if (!sent)
1095 return;
1096
1097 if (!status)
1098 hci_white_list_add(hdev, &sent->bdaddr, sent->bdaddr_type);
1099}
1100
1101static void hci_cc_le_del_from_white_list(struct hci_dev *hdev,
1102 struct sk_buff *skb)
1103{
1104 struct hci_cp_le_del_from_white_list *sent;
1105 __u8 status = *((__u8 *) skb->data);
1106
1107 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1108
1109 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST);
1110 if (!sent)
1111 return;
1112
1113 if (!status)
1114 hci_white_list_del(hdev, &sent->bdaddr, sent->bdaddr_type);
1115}
1116
Johan Hedberg9b008c02013-01-22 14:02:01 +02001117static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
1118 struct sk_buff *skb)
1119{
1120 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
1121
1122 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1123
1124 if (!rp->status)
1125 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +02001126}
1127
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001128static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1129 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001130{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001131 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001132 __u8 status = *((__u8 *) skb->data);
1133
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001134 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001135
Johan Hedberg06199cf2012-02-22 16:37:11 +02001136 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001137 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001138 return;
1139
Johan Hedberg8f984df2012-02-28 01:07:22 +02001140 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001141 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001142 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001143 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1144 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001145 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001146 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001147 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001148 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001149
1150 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001151 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001152 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001153 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001154 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001155}
1156
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02001157static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
1158{
1159 struct hci_cp_le_set_adv_param *cp;
1160 u8 status = *((u8 *) skb->data);
1161
1162 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1163
1164 if (status)
1165 return;
1166
1167 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM);
1168 if (!cp)
1169 return;
1170
1171 hci_dev_lock(hdev);
1172 hdev->adv_addr_type = cp->own_address_type;
1173 hci_dev_unlock(hdev);
1174}
1175
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001176static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1177 struct sk_buff *skb)
1178{
1179 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1180
1181 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1182 hdev->name, rp->status, rp->phy_handle);
1183
1184 if (rp->status)
1185 return;
1186
1187 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1188}
1189
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001190static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001191{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001192 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001193
1194 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001195 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001196 return;
1197 }
1198
Andre Guedes89352e72011-11-04 14:16:53 -03001199 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001200}
1201
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001202static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001204 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001207 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001208
1209 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 if (!cp)
1211 return;
1212
1213 hci_dev_lock(hdev);
1214
1215 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1216
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001217 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218
1219 if (status) {
1220 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001221 if (status != 0x0c || conn->attempt > 2) {
1222 conn->state = BT_CLOSED;
1223 hci_proto_connect_cfm(conn, status);
1224 hci_conn_del(conn);
1225 } else
1226 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001227 }
1228 } else {
1229 if (!conn) {
1230 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1231 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001232 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233 conn->link_mode |= HCI_LM_MASTER;
1234 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001235 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 }
1237 }
1238
1239 hci_dev_unlock(hdev);
1240}
1241
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001242static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001244 struct hci_cp_add_sco *cp;
1245 struct hci_conn *acl, *sco;
1246 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001248 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001249
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001250 if (!status)
1251 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001253 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1254 if (!cp)
1255 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001257 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001259 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001260
1261 hci_dev_lock(hdev);
1262
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001263 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001264 if (acl) {
1265 sco = acl->link;
1266 if (sco) {
1267 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001268
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001269 hci_proto_connect_cfm(sco, status);
1270 hci_conn_del(sco);
1271 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001272 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001273
1274 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275}
1276
Marcel Holtmannf8558552008-07-14 20:13:49 +02001277static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1278{
1279 struct hci_cp_auth_requested *cp;
1280 struct hci_conn *conn;
1281
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001282 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001283
1284 if (!status)
1285 return;
1286
1287 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1288 if (!cp)
1289 return;
1290
1291 hci_dev_lock(hdev);
1292
1293 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1294 if (conn) {
1295 if (conn->state == BT_CONFIG) {
1296 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001297 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001298 }
1299 }
1300
1301 hci_dev_unlock(hdev);
1302}
1303
1304static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1305{
1306 struct hci_cp_set_conn_encrypt *cp;
1307 struct hci_conn *conn;
1308
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001309 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001310
1311 if (!status)
1312 return;
1313
1314 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1315 if (!cp)
1316 return;
1317
1318 hci_dev_lock(hdev);
1319
1320 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1321 if (conn) {
1322 if (conn->state == BT_CONFIG) {
1323 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001324 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001325 }
1326 }
1327
1328 hci_dev_unlock(hdev);
1329}
1330
Johan Hedberg127178d2010-11-18 22:22:29 +02001331static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001332 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001333{
Johan Hedberg392599b2010-11-18 22:22:28 +02001334 if (conn->state != BT_CONFIG || !conn->out)
1335 return 0;
1336
Johan Hedberg765c2a92011-01-19 12:06:52 +05301337 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001338 return 0;
1339
1340 /* Only request authentication for SSP connections or non-SSP
Johan Hedberg264b8b42014-01-08 16:40:39 +02001341 * devices with sec_level MEDIUM or HIGH or if MITM protection
1342 * is requested.
1343 */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001344 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
Johan Hedberg264b8b42014-01-08 16:40:39 +02001345 conn->pending_sec_level != BT_SECURITY_HIGH &&
1346 conn->pending_sec_level != BT_SECURITY_MEDIUM)
Johan Hedberg392599b2010-11-18 22:22:28 +02001347 return 0;
1348
Johan Hedberg392599b2010-11-18 22:22:28 +02001349 return 1;
1350}
1351
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001352static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001353 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001354{
1355 struct hci_cp_remote_name_req cp;
1356
1357 memset(&cp, 0, sizeof(cp));
1358
1359 bacpy(&cp.bdaddr, &e->data.bdaddr);
1360 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1361 cp.pscan_mode = e->data.pscan_mode;
1362 cp.clock_offset = e->data.clock_offset;
1363
1364 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1365}
1366
Johan Hedbergb644ba32012-01-17 21:48:47 +02001367static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001368{
1369 struct discovery_state *discov = &hdev->discovery;
1370 struct inquiry_entry *e;
1371
Johan Hedbergb644ba32012-01-17 21:48:47 +02001372 if (list_empty(&discov->resolve))
1373 return false;
1374
1375 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001376 if (!e)
1377 return false;
1378
Johan Hedbergb644ba32012-01-17 21:48:47 +02001379 if (hci_resolve_name(hdev, e) == 0) {
1380 e->name_state = NAME_PENDING;
1381 return true;
1382 }
1383
1384 return false;
1385}
1386
1387static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001388 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001389{
1390 struct discovery_state *discov = &hdev->discovery;
1391 struct inquiry_entry *e;
1392
1393 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001394 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1395 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001396
1397 if (discov->state == DISCOVERY_STOPPED)
1398 return;
1399
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001400 if (discov->state == DISCOVERY_STOPPING)
1401 goto discov_complete;
1402
1403 if (discov->state != DISCOVERY_RESOLVING)
1404 return;
1405
1406 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001407 /* If the device was not found in a list of found devices names of which
1408 * are pending. there is no need to continue resolving a next name as it
1409 * will be done upon receiving another Remote Name Request Complete
1410 * Event */
1411 if (!e)
1412 return;
1413
1414 list_del(&e->list);
1415 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001416 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001417 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1418 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001419 } else {
1420 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001421 }
1422
Johan Hedbergb644ba32012-01-17 21:48:47 +02001423 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001424 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001425
1426discov_complete:
1427 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1428}
1429
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001430static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1431{
Johan Hedberg127178d2010-11-18 22:22:29 +02001432 struct hci_cp_remote_name_req *cp;
1433 struct hci_conn *conn;
1434
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001435 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001436
1437 /* If successful wait for the name req complete event before
1438 * checking for the need to do authentication */
1439 if (!status)
1440 return;
1441
1442 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1443 if (!cp)
1444 return;
1445
1446 hci_dev_lock(hdev);
1447
1448 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001449
1450 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1451 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1452
Johan Hedberg79c6c702011-04-28 11:28:55 -07001453 if (!conn)
1454 goto unlock;
1455
1456 if (!hci_outgoing_auth_needed(hdev, conn))
1457 goto unlock;
1458
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001459 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001460 struct hci_cp_auth_requested auth_cp;
1461
1462 auth_cp.handle = __cpu_to_le16(conn->handle);
1463 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1464 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001465 }
1466
Johan Hedberg79c6c702011-04-28 11:28:55 -07001467unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001468 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001469}
1470
Marcel Holtmann769be972008-07-14 20:13:49 +02001471static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1472{
1473 struct hci_cp_read_remote_features *cp;
1474 struct hci_conn *conn;
1475
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001476 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001477
1478 if (!status)
1479 return;
1480
1481 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1482 if (!cp)
1483 return;
1484
1485 hci_dev_lock(hdev);
1486
1487 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1488 if (conn) {
1489 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001490 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001491 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001492 }
1493 }
1494
1495 hci_dev_unlock(hdev);
1496}
1497
1498static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1499{
1500 struct hci_cp_read_remote_ext_features *cp;
1501 struct hci_conn *conn;
1502
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001503 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001504
1505 if (!status)
1506 return;
1507
1508 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1509 if (!cp)
1510 return;
1511
1512 hci_dev_lock(hdev);
1513
1514 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1515 if (conn) {
1516 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001517 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001518 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001519 }
1520 }
1521
1522 hci_dev_unlock(hdev);
1523}
1524
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001525static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1526{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001527 struct hci_cp_setup_sync_conn *cp;
1528 struct hci_conn *acl, *sco;
1529 __u16 handle;
1530
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001531 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001532
1533 if (!status)
1534 return;
1535
1536 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1537 if (!cp)
1538 return;
1539
1540 handle = __le16_to_cpu(cp->handle);
1541
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001542 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001543
1544 hci_dev_lock(hdev);
1545
1546 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001547 if (acl) {
1548 sco = acl->link;
1549 if (sco) {
1550 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001551
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001552 hci_proto_connect_cfm(sco, status);
1553 hci_conn_del(sco);
1554 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001555 }
1556
1557 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001558}
1559
1560static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1561{
1562 struct hci_cp_sniff_mode *cp;
1563 struct hci_conn *conn;
1564
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001565 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001566
1567 if (!status)
1568 return;
1569
1570 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1571 if (!cp)
1572 return;
1573
1574 hci_dev_lock(hdev);
1575
1576 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001577 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001578 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001579
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001580 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001581 hci_sco_setup(conn, status);
1582 }
1583
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001584 hci_dev_unlock(hdev);
1585}
1586
1587static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1588{
1589 struct hci_cp_exit_sniff_mode *cp;
1590 struct hci_conn *conn;
1591
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001592 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001593
1594 if (!status)
1595 return;
1596
1597 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1598 if (!cp)
1599 return;
1600
1601 hci_dev_lock(hdev);
1602
1603 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001604 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001605 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001606
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001607 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001608 hci_sco_setup(conn, status);
1609 }
1610
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001611 hci_dev_unlock(hdev);
1612}
1613
Johan Hedberg88c3df12012-02-09 14:27:38 +02001614static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1615{
1616 struct hci_cp_disconnect *cp;
1617 struct hci_conn *conn;
1618
1619 if (!status)
1620 return;
1621
1622 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1623 if (!cp)
1624 return;
1625
1626 hci_dev_lock(hdev);
1627
1628 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1629 if (conn)
1630 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001631 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001632
1633 hci_dev_unlock(hdev);
1634}
1635
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001636static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1637{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001638 struct hci_cp_create_phy_link *cp;
1639
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001640 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001641
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001642 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1643 if (!cp)
1644 return;
1645
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001646 hci_dev_lock(hdev);
1647
1648 if (status) {
1649 struct hci_conn *hcon;
1650
1651 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1652 if (hcon)
1653 hci_conn_del(hcon);
1654 } else {
1655 amp_write_remote_assoc(hdev, cp->phy_handle);
1656 }
1657
1658 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001659}
1660
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001661static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1662{
1663 struct hci_cp_accept_phy_link *cp;
1664
1665 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1666
1667 if (status)
1668 return;
1669
1670 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1671 if (!cp)
1672 return;
1673
1674 amp_write_remote_assoc(hdev, cp->phy_handle);
1675}
1676
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02001677static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
1678{
1679 struct hci_cp_le_create_conn *cp;
1680 struct hci_conn *conn;
1681
1682 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1683
1684 /* All connection failure handling is taken care of by the
1685 * hci_le_conn_failed function which is triggered by the HCI
1686 * request completion callbacks used for connecting.
1687 */
1688 if (status)
1689 return;
1690
1691 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1692 if (!cp)
1693 return;
1694
1695 hci_dev_lock(hdev);
1696
1697 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1698 if (!conn)
1699 goto unlock;
1700
1701 /* Store the initiator and responder address information which
1702 * is needed for SMP. These values will not change during the
1703 * lifetime of the connection.
1704 */
1705 conn->init_addr_type = cp->own_address_type;
1706 if (cp->own_address_type == ADDR_LE_DEV_RANDOM)
1707 bacpy(&conn->init_addr, &hdev->random_addr);
1708 else
1709 bacpy(&conn->init_addr, &hdev->bdaddr);
1710
1711 conn->resp_addr_type = cp->peer_addr_type;
1712 bacpy(&conn->resp_addr, &cp->peer_addr);
1713
Johan Hedberg9489eca2014-02-28 17:45:46 +02001714 /* We don't want the connection attempt to stick around
1715 * indefinitely since LE doesn't have a page timeout concept
1716 * like BR/EDR. Set a timer for any connection that doesn't use
1717 * the white list for connecting.
1718 */
1719 if (cp->filter_policy == HCI_LE_USE_PEER_ADDR)
1720 queue_delayed_work(conn->hdev->workqueue,
1721 &conn->le_conn_timeout,
1722 HCI_LE_CONN_TIMEOUT);
1723
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02001724unlock:
1725 hci_dev_unlock(hdev);
1726}
1727
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001728static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001729{
1730 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001731 struct discovery_state *discov = &hdev->discovery;
1732 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001733
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001734 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001735
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001736 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001737
1738 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1739 return;
1740
Andre Guedes3e13fa12013-03-27 20:04:56 -03001741 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1742 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1743
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001744 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001745 return;
1746
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001747 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001748
Andre Guedes343f9352012-02-17 20:39:37 -03001749 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001750 goto unlock;
1751
1752 if (list_empty(&discov->resolve)) {
1753 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1754 goto unlock;
1755 }
1756
1757 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1758 if (e && hci_resolve_name(hdev, e) == 0) {
1759 e->name_state = NAME_PENDING;
1760 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1761 } else {
1762 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1763 }
1764
1765unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001766 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001767}
1768
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001769static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001771 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001772 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 int num_rsp = *((__u8 *) skb->data);
1774
1775 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1776
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001777 if (!num_rsp)
1778 return;
1779
Andre Guedes1519cc12012-03-21 00:03:38 -03001780 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1781 return;
1782
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001784
Johan Hedberge17acd42011-03-30 23:57:16 +03001785 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001786 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001787
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 bacpy(&data.bdaddr, &info->bdaddr);
1789 data.pscan_rep_mode = info->pscan_rep_mode;
1790 data.pscan_period_mode = info->pscan_period_mode;
1791 data.pscan_mode = info->pscan_mode;
1792 memcpy(data.dev_class, info->dev_class, 3);
1793 data.clock_offset = info->clock_offset;
1794 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001795 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001796
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001797 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001798 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001799 info->dev_class, 0, !name_known, ssp, NULL,
1800 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001802
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 hci_dev_unlock(hdev);
1804}
1805
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001806static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001808 struct hci_ev_conn_complete *ev = (void *) skb->data;
1809 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001811 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001812
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001814
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001815 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001816 if (!conn) {
1817 if (ev->link_type != SCO_LINK)
1818 goto unlock;
1819
1820 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1821 if (!conn)
1822 goto unlock;
1823
1824 conn->type = SCO_LINK;
1825 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001826
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001827 if (!ev->status) {
1828 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001829
1830 if (conn->type == ACL_LINK) {
1831 conn->state = BT_CONFIG;
1832 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001833
1834 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1835 !hci_find_link_key(hdev, &ev->bdaddr))
1836 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1837 else
1838 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001839 } else
1840 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001841
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001842 hci_conn_add_sysfs(conn);
1843
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001844 if (test_bit(HCI_AUTH, &hdev->flags))
1845 conn->link_mode |= HCI_LM_AUTH;
1846
1847 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1848 conn->link_mode |= HCI_LM_ENCRYPT;
1849
1850 /* Get remote features */
1851 if (conn->type == ACL_LINK) {
1852 struct hci_cp_read_remote_features cp;
1853 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001854 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001855 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001856 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001857
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001858 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001859 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001860 struct hci_cp_change_conn_ptype cp;
1861 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001862 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001863 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1864 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001865 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001866 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001867 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001868 if (conn->type == ACL_LINK)
Marcel Holtmann64c7b772014-02-18 14:22:20 -08001869 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001870 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001871 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001872
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001873 if (conn->type == ACL_LINK)
1874 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001875
Marcel Holtmann769be972008-07-14 20:13:49 +02001876 if (ev->status) {
1877 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001878 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001879 } else if (ev->link_type != ACL_LINK)
1880 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001881
1882unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001884
1885 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886}
1887
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001888static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001890 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001892 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001894 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001895 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001897 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1898 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899
Szymon Janc138d22e2011-02-17 16:44:23 +01001900 if ((mask & HCI_LM_ACCEPT) &&
Marcel Holtmannb9ee0a72013-10-17 17:24:13 -07001901 !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001903 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905
1906 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001907
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001908 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1909 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001910 memcpy(ie->data.dev_class, ev->dev_class, 3);
1911
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001912 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1913 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001915 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1916 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001917 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918 hci_dev_unlock(hdev);
1919 return;
1920 }
1921 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001922
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001924
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 hci_dev_unlock(hdev);
1926
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001927 if (ev->link_type == ACL_LINK ||
1928 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001929 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001930 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001932 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001934 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1935 cp.role = 0x00; /* Become master */
1936 else
1937 cp.role = 0x01; /* Remain slave */
1938
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001939 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1940 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001941 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001942 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001943 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001944
1945 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001946 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001947
Joe Perchesdcf4adb2014-03-12 10:52:35 -07001948 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1949 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1950 cp.max_latency = cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001951 cp.content_format = cpu_to_le16(hdev->voice_setting);
1952 cp.retrans_effort = 0xff;
1953
1954 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001955 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001956 } else {
1957 conn->state = BT_CONNECT2;
1958 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001959 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960 } else {
1961 /* Connection rejected */
1962 struct hci_cp_reject_conn_req cp;
1963
1964 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001965 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001966 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001967 }
1968}
1969
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001970static u8 hci_to_mgmt_reason(u8 err)
1971{
1972 switch (err) {
1973 case HCI_ERROR_CONNECTION_TIMEOUT:
1974 return MGMT_DEV_DISCONN_TIMEOUT;
1975 case HCI_ERROR_REMOTE_USER_TERM:
1976 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1977 case HCI_ERROR_REMOTE_POWER_OFF:
1978 return MGMT_DEV_DISCONN_REMOTE;
1979 case HCI_ERROR_LOCAL_HOST_TERM:
1980 return MGMT_DEV_DISCONN_LOCAL_HOST;
1981 default:
1982 return MGMT_DEV_DISCONN_UNKNOWN;
1983 }
1984}
1985
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001986static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001988 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Andre Guedesabf54a52013-11-07 17:36:09 -03001989 u8 reason = hci_to_mgmt_reason(ev->reason);
Andre Guedes9fcb18e2014-02-26 20:21:48 -03001990 struct hci_conn_params *params;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001991 struct hci_conn *conn;
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02001992 bool mgmt_connected;
Andre Guedes38462202013-11-07 17:36:10 -03001993 u8 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001994
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001995 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001996
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997 hci_dev_lock(hdev);
1998
Marcel Holtmann04837f62006-07-03 10:02:33 +02001999 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02002000 if (!conn)
2001 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002002
Andre Guedesabf54a52013-11-07 17:36:09 -03002003 if (ev->status) {
2004 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
2005 conn->dst_type, ev->status);
2006 goto unlock;
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002007 }
Johan Hedbergf7520542011-01-20 12:34:39 +02002008
Andre Guedes38462202013-11-07 17:36:10 -03002009 conn->state = BT_CLOSED;
2010
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02002011 mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
2012 mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
2013 reason, mgmt_connected);
Andre Guedesabf54a52013-11-07 17:36:09 -03002014
Andre Guedes38462202013-11-07 17:36:10 -03002015 if (conn->type == ACL_LINK && conn->flush_key)
2016 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg22102462013-10-05 12:01:06 +02002017
Andre Guedes9fcb18e2014-02-26 20:21:48 -03002018 params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
2019 if (params) {
2020 switch (params->auto_connect) {
2021 case HCI_AUTO_CONN_LINK_LOSS:
2022 if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
2023 break;
2024 /* Fall through */
2025
2026 case HCI_AUTO_CONN_ALWAYS:
2027 hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type);
2028 break;
2029
2030 default:
2031 break;
2032 }
2033 }
2034
Andre Guedes38462202013-11-07 17:36:10 -03002035 type = conn->type;
Johan Hedberg22102462013-10-05 12:01:06 +02002036
Andre Guedes38462202013-11-07 17:36:10 -03002037 hci_proto_disconn_cfm(conn, ev->reason);
2038 hci_conn_del(conn);
2039
2040 /* Re-enable advertising if necessary, since it might
2041 * have been disabled by the connection. From the
2042 * HCI_LE_Set_Advertise_Enable command description in
2043 * the core specification (v4.0):
2044 * "The Controller shall continue advertising until the Host
2045 * issues an LE_Set_Advertise_Enable command with
2046 * Advertising_Enable set to 0x00 (Advertising is disabled)
2047 * or until a connection is created or until the Advertising
2048 * is timed out due to Directed Advertising."
2049 */
2050 if (type == LE_LINK)
2051 mgmt_reenable_advertising(hdev);
Johan Hedbergf7520542011-01-20 12:34:39 +02002052
2053unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054 hci_dev_unlock(hdev);
2055}
2056
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002057static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002058{
2059 struct hci_ev_auth_complete *ev = (void *) skb->data;
2060 struct hci_conn *conn;
2061
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002062 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002063
2064 hci_dev_lock(hdev);
2065
2066 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002067 if (!conn)
2068 goto unlock;
2069
2070 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002071 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002072 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002073 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03002074 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002075 conn->link_mode |= HCI_LM_AUTH;
2076 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03002077 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002078 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02002079 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002080 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002081 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002082
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002083 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
2084 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002085
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002086 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002087 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002088 struct hci_cp_set_conn_encrypt cp;
2089 cp.handle = ev->handle;
2090 cp.encrypt = 0x01;
2091 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002092 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002093 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002094 conn->state = BT_CONNECTED;
2095 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002096 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002097 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002098 } else {
2099 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002100
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002101 hci_conn_hold(conn);
2102 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002103 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002104 }
2105
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002106 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002107 if (!ev->status) {
2108 struct hci_cp_set_conn_encrypt cp;
2109 cp.handle = ev->handle;
2110 cp.encrypt = 0x01;
2111 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002112 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002113 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002114 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002115 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002116 }
2117 }
2118
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002119unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002120 hci_dev_unlock(hdev);
2121}
2122
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002123static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002124{
Johan Hedberg127178d2010-11-18 22:22:29 +02002125 struct hci_ev_remote_name *ev = (void *) skb->data;
2126 struct hci_conn *conn;
2127
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002128 BT_DBG("%s", hdev->name);
2129
2130 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02002131
2132 hci_dev_lock(hdev);
2133
2134 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002135
2136 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2137 goto check_auth;
2138
2139 if (ev->status == 0)
2140 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002141 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002142 else
2143 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2144
2145check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002146 if (!conn)
2147 goto unlock;
2148
2149 if (!hci_outgoing_auth_needed(hdev, conn))
2150 goto unlock;
2151
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002152 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002153 struct hci_cp_auth_requested cp;
2154 cp.handle = __cpu_to_le16(conn->handle);
2155 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2156 }
2157
Johan Hedberg79c6c702011-04-28 11:28:55 -07002158unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002159 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002160}
2161
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002162static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002163{
2164 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2165 struct hci_conn *conn;
2166
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002167 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002168
2169 hci_dev_lock(hdev);
2170
2171 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002172 if (!conn)
2173 goto unlock;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002174
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002175 if (!ev->status) {
2176 if (ev->encrypt) {
2177 /* Encryption implies authentication */
2178 conn->link_mode |= HCI_LM_AUTH;
2179 conn->link_mode |= HCI_LM_ENCRYPT;
2180 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002181
Marcel Holtmann914a6ff2014-02-01 11:52:02 -08002182 /* P-256 authentication key implies FIPS */
2183 if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
2184 conn->link_mode |= HCI_LM_FIPS;
2185
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002186 if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
2187 conn->type == LE_LINK)
2188 set_bit(HCI_CONN_AES_CCM, &conn->flags);
2189 } else {
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002190 conn->link_mode &= ~HCI_LM_ENCRYPT;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002191 clear_bit(HCI_CONN_AES_CCM, &conn->flags);
2192 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002193 }
2194
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002195 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2196
2197 if (ev->status && conn->state == BT_CONNECTED) {
2198 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
2199 hci_conn_drop(conn);
2200 goto unlock;
2201 }
2202
2203 if (conn->state == BT_CONFIG) {
2204 if (!ev->status)
2205 conn->state = BT_CONNECTED;
2206
Marcel Holtmann40b552a2014-03-19 14:10:25 -07002207 /* In Secure Connections Only mode, do not allow any
2208 * connections that are not encrypted with AES-CCM
2209 * using a P-256 authenticated combination key.
2210 */
2211 if (test_bit(HCI_SC_ONLY, &hdev->dev_flags) &&
2212 (!test_bit(HCI_CONN_AES_CCM, &conn->flags) ||
2213 conn->key_type != HCI_LK_AUTH_COMBINATION_P256)) {
2214 hci_proto_connect_cfm(conn, HCI_ERROR_AUTH_FAILURE);
2215 hci_conn_drop(conn);
2216 goto unlock;
2217 }
2218
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002219 hci_proto_connect_cfm(conn, ev->status);
2220 hci_conn_drop(conn);
2221 } else
2222 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
2223
Gustavo Padovana7d77232012-05-13 03:20:07 -03002224unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002225 hci_dev_unlock(hdev);
2226}
2227
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002228static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2229 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002230{
2231 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2232 struct hci_conn *conn;
2233
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002234 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002235
2236 hci_dev_lock(hdev);
2237
2238 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2239 if (conn) {
2240 if (!ev->status)
2241 conn->link_mode |= HCI_LM_SECURE;
2242
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002243 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002244
2245 hci_key_change_cfm(conn, ev->status);
2246 }
2247
2248 hci_dev_unlock(hdev);
2249}
2250
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002251static void hci_remote_features_evt(struct hci_dev *hdev,
2252 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002253{
2254 struct hci_ev_remote_features *ev = (void *) skb->data;
2255 struct hci_conn *conn;
2256
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002257 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002258
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002259 hci_dev_lock(hdev);
2260
2261 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002262 if (!conn)
2263 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002264
Johan Hedbergccd556f2010-11-10 17:11:51 +02002265 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002266 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002267
2268 if (conn->state != BT_CONFIG)
2269 goto unlock;
2270
2271 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2272 struct hci_cp_read_remote_ext_features cp;
2273 cp.handle = ev->handle;
2274 cp.page = 0x01;
2275 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002276 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002277 goto unlock;
2278 }
2279
Johan Hedberg671267b2012-05-12 16:11:50 -03002280 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002281 struct hci_cp_remote_name_req cp;
2282 memset(&cp, 0, sizeof(cp));
2283 bacpy(&cp.bdaddr, &conn->dst);
2284 cp.pscan_rep_mode = 0x02;
2285 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002286 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2287 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002288 conn->dst_type, 0, NULL, 0,
2289 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002290
Johan Hedberg127178d2010-11-18 22:22:29 +02002291 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002292 conn->state = BT_CONNECTED;
2293 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002294 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002295 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002296
Johan Hedbergccd556f2010-11-10 17:11:51 +02002297unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002298 hci_dev_unlock(hdev);
2299}
2300
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002301static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002302{
2303 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002304 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002305 __u16 opcode;
2306
2307 skb_pull(skb, sizeof(*ev));
2308
2309 opcode = __le16_to_cpu(ev->opcode);
2310
2311 switch (opcode) {
2312 case HCI_OP_INQUIRY_CANCEL:
2313 hci_cc_inquiry_cancel(hdev, skb);
2314 break;
2315
Andre Guedes4d934832012-03-21 00:03:35 -03002316 case HCI_OP_PERIODIC_INQ:
2317 hci_cc_periodic_inq(hdev, skb);
2318 break;
2319
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002320 case HCI_OP_EXIT_PERIODIC_INQ:
2321 hci_cc_exit_periodic_inq(hdev, skb);
2322 break;
2323
2324 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2325 hci_cc_remote_name_req_cancel(hdev, skb);
2326 break;
2327
2328 case HCI_OP_ROLE_DISCOVERY:
2329 hci_cc_role_discovery(hdev, skb);
2330 break;
2331
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002332 case HCI_OP_READ_LINK_POLICY:
2333 hci_cc_read_link_policy(hdev, skb);
2334 break;
2335
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002336 case HCI_OP_WRITE_LINK_POLICY:
2337 hci_cc_write_link_policy(hdev, skb);
2338 break;
2339
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002340 case HCI_OP_READ_DEF_LINK_POLICY:
2341 hci_cc_read_def_link_policy(hdev, skb);
2342 break;
2343
2344 case HCI_OP_WRITE_DEF_LINK_POLICY:
2345 hci_cc_write_def_link_policy(hdev, skb);
2346 break;
2347
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002348 case HCI_OP_RESET:
2349 hci_cc_reset(hdev, skb);
2350 break;
2351
2352 case HCI_OP_WRITE_LOCAL_NAME:
2353 hci_cc_write_local_name(hdev, skb);
2354 break;
2355
2356 case HCI_OP_READ_LOCAL_NAME:
2357 hci_cc_read_local_name(hdev, skb);
2358 break;
2359
2360 case HCI_OP_WRITE_AUTH_ENABLE:
2361 hci_cc_write_auth_enable(hdev, skb);
2362 break;
2363
2364 case HCI_OP_WRITE_ENCRYPT_MODE:
2365 hci_cc_write_encrypt_mode(hdev, skb);
2366 break;
2367
2368 case HCI_OP_WRITE_SCAN_ENABLE:
2369 hci_cc_write_scan_enable(hdev, skb);
2370 break;
2371
2372 case HCI_OP_READ_CLASS_OF_DEV:
2373 hci_cc_read_class_of_dev(hdev, skb);
2374 break;
2375
2376 case HCI_OP_WRITE_CLASS_OF_DEV:
2377 hci_cc_write_class_of_dev(hdev, skb);
2378 break;
2379
2380 case HCI_OP_READ_VOICE_SETTING:
2381 hci_cc_read_voice_setting(hdev, skb);
2382 break;
2383
2384 case HCI_OP_WRITE_VOICE_SETTING:
2385 hci_cc_write_voice_setting(hdev, skb);
2386 break;
2387
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002388 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2389 hci_cc_read_num_supported_iac(hdev, skb);
2390 break;
2391
Marcel Holtmann333140b2008-07-14 20:13:48 +02002392 case HCI_OP_WRITE_SSP_MODE:
2393 hci_cc_write_ssp_mode(hdev, skb);
2394 break;
2395
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08002396 case HCI_OP_WRITE_SC_SUPPORT:
2397 hci_cc_write_sc_support(hdev, skb);
2398 break;
2399
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002400 case HCI_OP_READ_LOCAL_VERSION:
2401 hci_cc_read_local_version(hdev, skb);
2402 break;
2403
2404 case HCI_OP_READ_LOCAL_COMMANDS:
2405 hci_cc_read_local_commands(hdev, skb);
2406 break;
2407
2408 case HCI_OP_READ_LOCAL_FEATURES:
2409 hci_cc_read_local_features(hdev, skb);
2410 break;
2411
Andre Guedes971e3a42011-06-30 19:20:52 -03002412 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2413 hci_cc_read_local_ext_features(hdev, skb);
2414 break;
2415
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002416 case HCI_OP_READ_BUFFER_SIZE:
2417 hci_cc_read_buffer_size(hdev, skb);
2418 break;
2419
2420 case HCI_OP_READ_BD_ADDR:
2421 hci_cc_read_bd_addr(hdev, skb);
2422 break;
2423
Johan Hedbergf332ec62013-03-15 17:07:11 -05002424 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2425 hci_cc_read_page_scan_activity(hdev, skb);
2426 break;
2427
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002428 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2429 hci_cc_write_page_scan_activity(hdev, skb);
2430 break;
2431
Johan Hedbergf332ec62013-03-15 17:07:11 -05002432 case HCI_OP_READ_PAGE_SCAN_TYPE:
2433 hci_cc_read_page_scan_type(hdev, skb);
2434 break;
2435
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002436 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2437 hci_cc_write_page_scan_type(hdev, skb);
2438 break;
2439
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002440 case HCI_OP_READ_DATA_BLOCK_SIZE:
2441 hci_cc_read_data_block_size(hdev, skb);
2442 break;
2443
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002444 case HCI_OP_READ_FLOW_CONTROL_MODE:
2445 hci_cc_read_flow_control_mode(hdev, skb);
2446 break;
2447
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002448 case HCI_OP_READ_LOCAL_AMP_INFO:
2449 hci_cc_read_local_amp_info(hdev, skb);
2450 break;
2451
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002452 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2453 hci_cc_read_local_amp_assoc(hdev, skb);
2454 break;
2455
Johan Hedbergd5859e22011-01-25 01:19:58 +02002456 case HCI_OP_READ_INQ_RSP_TX_POWER:
2457 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2458 break;
2459
Johan Hedberg980e1a52011-01-22 06:10:07 +02002460 case HCI_OP_PIN_CODE_REPLY:
2461 hci_cc_pin_code_reply(hdev, skb);
2462 break;
2463
2464 case HCI_OP_PIN_CODE_NEG_REPLY:
2465 hci_cc_pin_code_neg_reply(hdev, skb);
2466 break;
2467
Szymon Jancc35938b2011-03-22 13:12:21 +01002468 case HCI_OP_READ_LOCAL_OOB_DATA:
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08002469 hci_cc_read_local_oob_data(hdev, skb);
2470 break;
2471
2472 case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
2473 hci_cc_read_local_oob_ext_data(hdev, skb);
Szymon Jancc35938b2011-03-22 13:12:21 +01002474 break;
2475
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002476 case HCI_OP_LE_READ_BUFFER_SIZE:
2477 hci_cc_le_read_buffer_size(hdev, skb);
2478 break;
2479
Johan Hedberg60e77322013-01-22 14:01:59 +02002480 case HCI_OP_LE_READ_LOCAL_FEATURES:
2481 hci_cc_le_read_local_features(hdev, skb);
2482 break;
2483
Johan Hedberg8fa19092012-10-19 20:57:49 +03002484 case HCI_OP_LE_READ_ADV_TX_POWER:
2485 hci_cc_le_read_adv_tx_power(hdev, skb);
2486 break;
2487
Johan Hedberga5c29682011-02-19 12:05:57 -03002488 case HCI_OP_USER_CONFIRM_REPLY:
2489 hci_cc_user_confirm_reply(hdev, skb);
2490 break;
2491
2492 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2493 hci_cc_user_confirm_neg_reply(hdev, skb);
2494 break;
2495
Brian Gix1143d452011-11-23 08:28:34 -08002496 case HCI_OP_USER_PASSKEY_REPLY:
2497 hci_cc_user_passkey_reply(hdev, skb);
2498 break;
2499
2500 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2501 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002502 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002503
Marcel Holtmann7a4cd512014-02-19 19:52:13 -08002504 case HCI_OP_LE_SET_RANDOM_ADDR:
2505 hci_cc_le_set_random_addr(hdev, skb);
2506 break;
2507
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002508 case HCI_OP_LE_SET_ADV_ENABLE:
2509 hci_cc_le_set_adv_enable(hdev, skb);
2510 break;
2511
Marcel Holtmann533553f2014-03-21 12:18:10 -07002512 case HCI_OP_LE_SET_SCAN_PARAM:
2513 hci_cc_le_set_scan_param(hdev, skb);
2514 break;
2515
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002516 case HCI_OP_LE_SET_SCAN_ENABLE:
2517 hci_cc_le_set_scan_enable(hdev, skb);
2518 break;
2519
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002520 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2521 hci_cc_le_read_white_list_size(hdev, skb);
2522 break;
2523
Marcel Holtmann0f36b582014-02-27 20:37:31 -08002524 case HCI_OP_LE_CLEAR_WHITE_LIST:
2525 hci_cc_le_clear_white_list(hdev, skb);
2526 break;
2527
2528 case HCI_OP_LE_ADD_TO_WHITE_LIST:
2529 hci_cc_le_add_to_white_list(hdev, skb);
2530 break;
2531
2532 case HCI_OP_LE_DEL_FROM_WHITE_LIST:
2533 hci_cc_le_del_from_white_list(hdev, skb);
2534 break;
2535
Johan Hedberg9b008c02013-01-22 14:02:01 +02002536 case HCI_OP_LE_READ_SUPPORTED_STATES:
2537 hci_cc_le_read_supported_states(hdev, skb);
2538 break;
2539
Andre Guedesf9b49302011-06-30 19:20:53 -03002540 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2541 hci_cc_write_le_host_supported(hdev, skb);
2542 break;
2543
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02002544 case HCI_OP_LE_SET_ADV_PARAM:
2545 hci_cc_set_adv_param(hdev, skb);
2546 break;
2547
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002548 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2549 hci_cc_write_remote_amp_assoc(hdev, skb);
2550 break;
2551
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002552 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002553 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002554 break;
2555 }
2556
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002557 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002558 del_timer(&hdev->cmd_timer);
2559
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002560 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002561
Szymon Jancdbccd792012-12-11 08:51:19 +01002562 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002563 atomic_set(&hdev->cmd_cnt, 1);
2564 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002565 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002566 }
2567}
2568
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002569static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002570{
2571 struct hci_ev_cmd_status *ev = (void *) skb->data;
2572 __u16 opcode;
2573
2574 skb_pull(skb, sizeof(*ev));
2575
2576 opcode = __le16_to_cpu(ev->opcode);
2577
2578 switch (opcode) {
2579 case HCI_OP_INQUIRY:
2580 hci_cs_inquiry(hdev, ev->status);
2581 break;
2582
2583 case HCI_OP_CREATE_CONN:
2584 hci_cs_create_conn(hdev, ev->status);
2585 break;
2586
2587 case HCI_OP_ADD_SCO:
2588 hci_cs_add_sco(hdev, ev->status);
2589 break;
2590
Marcel Holtmannf8558552008-07-14 20:13:49 +02002591 case HCI_OP_AUTH_REQUESTED:
2592 hci_cs_auth_requested(hdev, ev->status);
2593 break;
2594
2595 case HCI_OP_SET_CONN_ENCRYPT:
2596 hci_cs_set_conn_encrypt(hdev, ev->status);
2597 break;
2598
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002599 case HCI_OP_REMOTE_NAME_REQ:
2600 hci_cs_remote_name_req(hdev, ev->status);
2601 break;
2602
Marcel Holtmann769be972008-07-14 20:13:49 +02002603 case HCI_OP_READ_REMOTE_FEATURES:
2604 hci_cs_read_remote_features(hdev, ev->status);
2605 break;
2606
2607 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2608 hci_cs_read_remote_ext_features(hdev, ev->status);
2609 break;
2610
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002611 case HCI_OP_SETUP_SYNC_CONN:
2612 hci_cs_setup_sync_conn(hdev, ev->status);
2613 break;
2614
2615 case HCI_OP_SNIFF_MODE:
2616 hci_cs_sniff_mode(hdev, ev->status);
2617 break;
2618
2619 case HCI_OP_EXIT_SNIFF_MODE:
2620 hci_cs_exit_sniff_mode(hdev, ev->status);
2621 break;
2622
Johan Hedberg8962ee72011-01-20 12:40:27 +02002623 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002624 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002625 break;
2626
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002627 case HCI_OP_CREATE_PHY_LINK:
2628 hci_cs_create_phylink(hdev, ev->status);
2629 break;
2630
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002631 case HCI_OP_ACCEPT_PHY_LINK:
2632 hci_cs_accept_phylink(hdev, ev->status);
2633 break;
2634
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02002635 case HCI_OP_LE_CREATE_CONN:
2636 hci_cs_le_create_conn(hdev, ev->status);
2637 break;
2638
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002639 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002640 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002641 break;
2642 }
2643
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002644 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002645 del_timer(&hdev->cmd_timer);
2646
Johan Hedberg02350a72013-04-03 21:50:29 +03002647 if (ev->status ||
2648 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2649 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002650
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002651 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002652 atomic_set(&hdev->cmd_cnt, 1);
2653 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002654 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002655 }
2656}
2657
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002658static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002659{
2660 struct hci_ev_role_change *ev = (void *) skb->data;
2661 struct hci_conn *conn;
2662
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002663 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002664
2665 hci_dev_lock(hdev);
2666
2667 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2668 if (conn) {
2669 if (!ev->status) {
2670 if (ev->role)
2671 conn->link_mode &= ~HCI_LM_MASTER;
2672 else
2673 conn->link_mode |= HCI_LM_MASTER;
2674 }
2675
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002676 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002677
2678 hci_role_switch_cfm(conn, ev->status, ev->role);
2679 }
2680
2681 hci_dev_unlock(hdev);
2682}
2683
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002684static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002685{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002686 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002687 int i;
2688
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002689 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2690 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2691 return;
2692 }
2693
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002694 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002695 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696 BT_DBG("%s bad parameters", hdev->name);
2697 return;
2698 }
2699
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002700 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2701
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002702 for (i = 0; i < ev->num_hndl; i++) {
2703 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704 struct hci_conn *conn;
2705 __u16 handle, count;
2706
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002707 handle = __le16_to_cpu(info->handle);
2708 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002709
2710 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002711 if (!conn)
2712 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002713
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002714 conn->sent -= count;
2715
2716 switch (conn->type) {
2717 case ACL_LINK:
2718 hdev->acl_cnt += count;
2719 if (hdev->acl_cnt > hdev->acl_pkts)
2720 hdev->acl_cnt = hdev->acl_pkts;
2721 break;
2722
2723 case LE_LINK:
2724 if (hdev->le_pkts) {
2725 hdev->le_cnt += count;
2726 if (hdev->le_cnt > hdev->le_pkts)
2727 hdev->le_cnt = hdev->le_pkts;
2728 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002729 hdev->acl_cnt += count;
2730 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002731 hdev->acl_cnt = hdev->acl_pkts;
2732 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002733 break;
2734
2735 case SCO_LINK:
2736 hdev->sco_cnt += count;
2737 if (hdev->sco_cnt > hdev->sco_pkts)
2738 hdev->sco_cnt = hdev->sco_pkts;
2739 break;
2740
2741 default:
2742 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2743 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002744 }
2745 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002746
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002747 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002748}
2749
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002750static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2751 __u16 handle)
2752{
2753 struct hci_chan *chan;
2754
2755 switch (hdev->dev_type) {
2756 case HCI_BREDR:
2757 return hci_conn_hash_lookup_handle(hdev, handle);
2758 case HCI_AMP:
2759 chan = hci_chan_lookup_handle(hdev, handle);
2760 if (chan)
2761 return chan->conn;
2762 break;
2763 default:
2764 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2765 break;
2766 }
2767
2768 return NULL;
2769}
2770
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002771static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002772{
2773 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2774 int i;
2775
2776 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2777 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2778 return;
2779 }
2780
2781 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002782 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002783 BT_DBG("%s bad parameters", hdev->name);
2784 return;
2785 }
2786
2787 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002788 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002789
2790 for (i = 0; i < ev->num_hndl; i++) {
2791 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002792 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002793 __u16 handle, block_count;
2794
2795 handle = __le16_to_cpu(info->handle);
2796 block_count = __le16_to_cpu(info->blocks);
2797
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002798 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002799 if (!conn)
2800 continue;
2801
2802 conn->sent -= block_count;
2803
2804 switch (conn->type) {
2805 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002806 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002807 hdev->block_cnt += block_count;
2808 if (hdev->block_cnt > hdev->num_blocks)
2809 hdev->block_cnt = hdev->num_blocks;
2810 break;
2811
2812 default:
2813 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2814 break;
2815 }
2816 }
2817
2818 queue_work(hdev->workqueue, &hdev->tx_work);
2819}
2820
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002821static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002822{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002823 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002824 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002825
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002826 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002827
2828 hci_dev_lock(hdev);
2829
Marcel Holtmann04837f62006-07-03 10:02:33 +02002830 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2831 if (conn) {
2832 conn->mode = ev->mode;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002833
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002834 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2835 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002836 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002837 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002838 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002839 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002840 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002841
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002842 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002843 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002844 }
2845
2846 hci_dev_unlock(hdev);
2847}
2848
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002849static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002851 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2852 struct hci_conn *conn;
2853
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002854 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002855
2856 hci_dev_lock(hdev);
2857
2858 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002859 if (!conn)
2860 goto unlock;
2861
2862 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002863 hci_conn_hold(conn);
2864 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002865 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002866 }
2867
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002868 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002869 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002870 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002871 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002872 u8 secure;
2873
2874 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2875 secure = 1;
2876 else
2877 secure = 0;
2878
Johan Hedberg744cf192011-11-08 20:40:14 +02002879 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002880 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002881
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002882unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002883 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884}
2885
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002886static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002888 struct hci_ev_link_key_req *ev = (void *) skb->data;
2889 struct hci_cp_link_key_reply cp;
2890 struct hci_conn *conn;
2891 struct link_key *key;
2892
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002893 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002894
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002895 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002896 return;
2897
2898 hci_dev_lock(hdev);
2899
2900 key = hci_find_link_key(hdev, &ev->bdaddr);
2901 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002902 BT_DBG("%s link key not found for %pMR", hdev->name,
2903 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002904 goto not_found;
2905 }
2906
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002907 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2908 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002909
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002910 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002911 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002912 BT_DBG("%s ignoring debug key", hdev->name);
2913 goto not_found;
2914 }
2915
2916 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002917 if (conn) {
Marcel Holtmann66138ce2014-01-10 02:07:20 -08002918 if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
2919 key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002920 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002921 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2922 goto not_found;
2923 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002924
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002925 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002926 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002927 BT_DBG("%s ignoring key unauthenticated for high security",
2928 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002929 goto not_found;
2930 }
2931
2932 conn->key_type = key->type;
2933 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002934 }
2935
2936 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002937 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002938
2939 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2940
2941 hci_dev_unlock(hdev);
2942
2943 return;
2944
2945not_found:
2946 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2947 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948}
2949
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002950static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002951{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002952 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2953 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002954 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002955
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002956 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002957
2958 hci_dev_lock(hdev);
2959
2960 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2961 if (conn) {
2962 hci_conn_hold(conn);
2963 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002964 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002965
2966 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2967 conn->key_type = ev->key_type;
2968
David Herrmann76a68ba2013-04-06 20:28:37 +02002969 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002970 }
2971
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002972 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002973 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002974 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002975
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002976 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977}
2978
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002979static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002980{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002981 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002982 struct hci_conn *conn;
2983
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002984 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002985
2986 hci_dev_lock(hdev);
2987
2988 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002989 if (conn && !ev->status) {
2990 struct inquiry_entry *ie;
2991
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002992 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2993 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002994 ie->data.clock_offset = ev->clock_offset;
2995 ie->timestamp = jiffies;
2996 }
2997 }
2998
2999 hci_dev_unlock(hdev);
3000}
3001
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003002static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02003003{
3004 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
3005 struct hci_conn *conn;
3006
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003007 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02003008
3009 hci_dev_lock(hdev);
3010
3011 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3012 if (conn && !ev->status)
3013 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
3014
3015 hci_dev_unlock(hdev);
3016}
3017
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003018static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003019{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003020 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003021 struct inquiry_entry *ie;
3022
3023 BT_DBG("%s", hdev->name);
3024
3025 hci_dev_lock(hdev);
3026
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003027 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3028 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003029 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
3030 ie->timestamp = jiffies;
3031 }
3032
3033 hci_dev_unlock(hdev);
3034}
3035
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003036static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
3037 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003038{
3039 struct inquiry_data data;
3040 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003041 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003042
3043 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3044
3045 if (!num_rsp)
3046 return;
3047
Andre Guedes1519cc12012-03-21 00:03:38 -03003048 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3049 return;
3050
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003051 hci_dev_lock(hdev);
3052
3053 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01003054 struct inquiry_info_with_rssi_and_pscan_mode *info;
3055 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003056
Johan Hedberge17acd42011-03-30 23:57:16 +03003057 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003058 bacpy(&data.bdaddr, &info->bdaddr);
3059 data.pscan_rep_mode = info->pscan_rep_mode;
3060 data.pscan_period_mode = info->pscan_period_mode;
3061 data.pscan_mode = info->pscan_mode;
3062 memcpy(data.dev_class, info->dev_class, 3);
3063 data.clock_offset = info->clock_offset;
3064 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003065 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003066
3067 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003068 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003069 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003070 info->dev_class, info->rssi,
3071 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003072 }
3073 } else {
3074 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
3075
Johan Hedberge17acd42011-03-30 23:57:16 +03003076 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003077 bacpy(&data.bdaddr, &info->bdaddr);
3078 data.pscan_rep_mode = info->pscan_rep_mode;
3079 data.pscan_period_mode = info->pscan_period_mode;
3080 data.pscan_mode = 0x00;
3081 memcpy(data.dev_class, info->dev_class, 3);
3082 data.clock_offset = info->clock_offset;
3083 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003084 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003085 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003086 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003087 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003088 info->dev_class, info->rssi,
3089 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003090 }
3091 }
3092
3093 hci_dev_unlock(hdev);
3094}
3095
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003096static void hci_remote_ext_features_evt(struct hci_dev *hdev,
3097 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003098{
Marcel Holtmann41a96212008-07-14 20:13:48 +02003099 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
3100 struct hci_conn *conn;
3101
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003102 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003103
Marcel Holtmann41a96212008-07-14 20:13:48 +02003104 hci_dev_lock(hdev);
3105
3106 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02003107 if (!conn)
3108 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003109
Johan Hedbergcad718e2013-04-17 15:00:51 +03003110 if (ev->page < HCI_MAX_PAGES)
3111 memcpy(conn->features[ev->page], ev->features, 8);
3112
Johan Hedbergccd556f2010-11-10 17:11:51 +02003113 if (!ev->status && ev->page == 0x01) {
3114 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003115
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003116 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3117 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003118 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02003119
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05303120 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02003121 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05303122 } else {
3123 /* It is mandatory by the Bluetooth specification that
3124 * Extended Inquiry Results are only used when Secure
3125 * Simple Pairing is enabled, but some devices violate
3126 * this.
3127 *
3128 * To make these devices work, the internal SSP
3129 * enabled flag needs to be cleared if the remote host
3130 * features do not indicate SSP support */
3131 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
3132 }
Marcel Holtmanneb9a8f32014-01-15 22:37:38 -08003133
3134 if (ev->features[0] & LMP_HOST_SC)
3135 set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003136 }
3137
Johan Hedbergccd556f2010-11-10 17:11:51 +02003138 if (conn->state != BT_CONFIG)
3139 goto unlock;
3140
Johan Hedberg671267b2012-05-12 16:11:50 -03003141 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02003142 struct hci_cp_remote_name_req cp;
3143 memset(&cp, 0, sizeof(cp));
3144 bacpy(&cp.bdaddr, &conn->dst);
3145 cp.pscan_rep_mode = 0x02;
3146 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02003147 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3148 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003149 conn->dst_type, 0, NULL, 0,
3150 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02003151
Johan Hedberg127178d2010-11-18 22:22:29 +02003152 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02003153 conn->state = BT_CONNECTED;
3154 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003155 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02003156 }
3157
3158unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02003159 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003160}
3161
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003162static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
3163 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003164{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003165 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
3166 struct hci_conn *conn;
3167
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003168 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003169
3170 hci_dev_lock(hdev);
3171
3172 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02003173 if (!conn) {
3174 if (ev->link_type == ESCO_LINK)
3175 goto unlock;
3176
3177 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
3178 if (!conn)
3179 goto unlock;
3180
3181 conn->type = SCO_LINK;
3182 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003183
Marcel Holtmann732547f2009-04-19 19:14:14 +02003184 switch (ev->status) {
3185 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003186 conn->handle = __le16_to_cpu(ev->handle);
3187 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02003188
3189 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02003190 break;
3191
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02003192 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05003193 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003194 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08003195 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003196 case 0x1f: /* Unspecified error */
Andrew Earl27539bc2014-03-10 10:31:04 +00003197 case 0x20: /* Unsupported LMP Parameter value */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003198 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02003199 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
3200 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003201 if (hci_setup_sync(conn, conn->link->handle))
3202 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003203 }
3204 /* fall through */
3205
3206 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003207 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003208 break;
3209 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003210
3211 hci_proto_connect_cfm(conn, ev->status);
3212 if (ev->status)
3213 hci_conn_del(conn);
3214
3215unlock:
3216 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003217}
3218
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07003219static inline size_t eir_get_length(u8 *eir, size_t eir_len)
3220{
3221 size_t parsed = 0;
3222
3223 while (parsed < eir_len) {
3224 u8 field_len = eir[0];
3225
3226 if (field_len == 0)
3227 return parsed;
3228
3229 parsed += field_len + 1;
3230 eir += field_len + 1;
3231 }
3232
3233 return eir_len;
3234}
3235
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003236static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3237 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003238{
3239 struct inquiry_data data;
3240 struct extended_inquiry_info *info = (void *) (skb->data + 1);
3241 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303242 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003243
3244 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3245
3246 if (!num_rsp)
3247 return;
3248
Andre Guedes1519cc12012-03-21 00:03:38 -03003249 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3250 return;
3251
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003252 hci_dev_lock(hdev);
3253
Johan Hedberge17acd42011-03-30 23:57:16 +03003254 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003255 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003256
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003257 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003258 data.pscan_rep_mode = info->pscan_rep_mode;
3259 data.pscan_period_mode = info->pscan_period_mode;
3260 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003261 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003262 data.clock_offset = info->clock_offset;
3263 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003264 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003265
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003266 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003267 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003268 sizeof(info->data),
3269 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003270 else
3271 name_known = true;
3272
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003273 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003274 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303275 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003276 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003277 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303278 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003279 }
3280
3281 hci_dev_unlock(hdev);
3282}
3283
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003284static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3285 struct sk_buff *skb)
3286{
3287 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3288 struct hci_conn *conn;
3289
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003290 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003291 __le16_to_cpu(ev->handle));
3292
3293 hci_dev_lock(hdev);
3294
3295 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3296 if (!conn)
3297 goto unlock;
3298
3299 if (!ev->status)
3300 conn->sec_level = conn->pending_sec_level;
3301
3302 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3303
3304 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003305 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003306 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003307 goto unlock;
3308 }
3309
3310 if (conn->state == BT_CONFIG) {
3311 if (!ev->status)
3312 conn->state = BT_CONNECTED;
3313
3314 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003315 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003316 } else {
3317 hci_auth_cfm(conn, ev->status);
3318
3319 hci_conn_hold(conn);
3320 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003321 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003322 }
3323
3324unlock:
3325 hci_dev_unlock(hdev);
3326}
3327
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003328static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003329{
3330 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003331 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3332 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003333 /* If both remote and local IO capabilities allow MITM
3334 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003335 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3336 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3337 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003338 else
Mikel Astizacabae92013-06-28 10:56:28 +02003339 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003340 }
3341
3342 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003343 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3344 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003345 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003346
3347 return conn->auth_type;
3348}
3349
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003350static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003351{
3352 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3353 struct hci_conn *conn;
3354
3355 BT_DBG("%s", hdev->name);
3356
3357 hci_dev_lock(hdev);
3358
3359 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003360 if (!conn)
3361 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003362
Johan Hedberg03b555e2011-01-04 15:40:05 +02003363 hci_conn_hold(conn);
3364
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003365 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003366 goto unlock;
3367
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003368 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003369 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003370 struct hci_cp_io_capability_reply cp;
3371
3372 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303373 /* Change the IO capability from KeyboardDisplay
3374 * to DisplayYesNo as it is not supported by BT spec. */
3375 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003376 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003377 conn->auth_type = hci_get_auth_req(conn);
3378 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003379
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003380 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3381 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003382 cp.oob_data = 0x01;
3383 else
3384 cp.oob_data = 0x00;
3385
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003386 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003387 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003388 } else {
3389 struct hci_cp_io_capability_neg_reply cp;
3390
3391 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003392 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003393
3394 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003395 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003396 }
3397
3398unlock:
3399 hci_dev_unlock(hdev);
3400}
3401
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003402static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003403{
3404 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3405 struct hci_conn *conn;
3406
3407 BT_DBG("%s", hdev->name);
3408
3409 hci_dev_lock(hdev);
3410
3411 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3412 if (!conn)
3413 goto unlock;
3414
Johan Hedberg03b555e2011-01-04 15:40:05 +02003415 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003416 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003417 if (ev->oob_data)
3418 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003419
3420unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003421 hci_dev_unlock(hdev);
3422}
3423
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003424static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3425 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003426{
3427 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003428 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003429 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003430
3431 BT_DBG("%s", hdev->name);
3432
3433 hci_dev_lock(hdev);
3434
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003435 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003436 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003437
Johan Hedberg7a828902011-04-28 11:28:53 -07003438 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3439 if (!conn)
3440 goto unlock;
3441
3442 loc_mitm = (conn->auth_type & 0x01);
3443 rem_mitm = (conn->remote_auth & 0x01);
3444
3445 /* If we require MITM but the remote device can't provide that
3446 * (it has NoInputNoOutput) then reject the confirmation
3447 * request. The only exception is when we're dedicated bonding
3448 * initiators (connect_cfm_cb set) since then we always have the MITM
3449 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003450 if (!conn->connect_cfm_cb && loc_mitm &&
3451 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003452 BT_DBG("Rejecting request: remote device can't provide MITM");
3453 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003454 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003455 goto unlock;
3456 }
3457
3458 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003459 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3460 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003461
3462 /* If we're not the initiators request authorization to
3463 * proceed from user space (mgmt_user_confirm with
3464 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003465 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003466 BT_DBG("Confirming auto-accept as acceptor");
3467 confirm_hint = 1;
3468 goto confirm;
3469 }
3470
Johan Hedberg9f616562011-04-28 11:28:54 -07003471 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003472 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003473
3474 if (hdev->auto_accept_delay > 0) {
3475 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
Johan Hedberg7bc18d92013-10-16 18:11:39 +03003476 queue_delayed_work(conn->hdev->workqueue,
3477 &conn->auto_accept_work, delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003478 goto unlock;
3479 }
3480
Johan Hedberg7a828902011-04-28 11:28:53 -07003481 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003482 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003483 goto unlock;
3484 }
3485
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003486confirm:
Johan Hedberg39adbff2014-03-20 08:18:14 +02003487 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0,
3488 le32_to_cpu(ev->passkey), confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003489
3490unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003491 hci_dev_unlock(hdev);
3492}
3493
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003494static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3495 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003496{
3497 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3498
3499 BT_DBG("%s", hdev->name);
3500
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003501 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003502 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003503}
3504
Johan Hedberg92a25252012-09-06 18:39:26 +03003505static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3506 struct sk_buff *skb)
3507{
3508 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3509 struct hci_conn *conn;
3510
3511 BT_DBG("%s", hdev->name);
3512
3513 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3514 if (!conn)
3515 return;
3516
3517 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3518 conn->passkey_entered = 0;
3519
3520 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3521 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3522 conn->dst_type, conn->passkey_notify,
3523 conn->passkey_entered);
3524}
3525
3526static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3527{
3528 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3529 struct hci_conn *conn;
3530
3531 BT_DBG("%s", hdev->name);
3532
3533 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3534 if (!conn)
3535 return;
3536
3537 switch (ev->type) {
3538 case HCI_KEYPRESS_STARTED:
3539 conn->passkey_entered = 0;
3540 return;
3541
3542 case HCI_KEYPRESS_ENTERED:
3543 conn->passkey_entered++;
3544 break;
3545
3546 case HCI_KEYPRESS_ERASED:
3547 conn->passkey_entered--;
3548 break;
3549
3550 case HCI_KEYPRESS_CLEARED:
3551 conn->passkey_entered = 0;
3552 break;
3553
3554 case HCI_KEYPRESS_COMPLETED:
3555 return;
3556 }
3557
3558 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3559 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3560 conn->dst_type, conn->passkey_notify,
3561 conn->passkey_entered);
3562}
3563
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003564static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3565 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003566{
3567 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3568 struct hci_conn *conn;
3569
3570 BT_DBG("%s", hdev->name);
3571
3572 hci_dev_lock(hdev);
3573
3574 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003575 if (!conn)
3576 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003577
Johan Hedberg2a611692011-02-19 12:06:00 -03003578 /* To avoid duplicate auth_failed events to user space we check
3579 * the HCI_CONN_AUTH_PEND flag which will be set if we
3580 * initiated the authentication. A traditional auth_complete
3581 * event gets always produced as initiator and is also mapped to
3582 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003583 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003584 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003585 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003586
David Herrmann76a68ba2013-04-06 20:28:37 +02003587 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003588
3589unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003590 hci_dev_unlock(hdev);
3591}
3592
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003593static void hci_remote_host_features_evt(struct hci_dev *hdev,
3594 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003595{
3596 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3597 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003598 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003599
3600 BT_DBG("%s", hdev->name);
3601
3602 hci_dev_lock(hdev);
3603
Johan Hedbergcad718e2013-04-17 15:00:51 +03003604 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3605 if (conn)
3606 memcpy(conn->features[1], ev->features, 8);
3607
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003608 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3609 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003610 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003611
3612 hci_dev_unlock(hdev);
3613}
3614
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003615static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3616 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003617{
3618 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3619 struct oob_data *data;
3620
3621 BT_DBG("%s", hdev->name);
3622
3623 hci_dev_lock(hdev);
3624
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003625 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003626 goto unlock;
3627
Szymon Janc2763eda2011-03-22 13:12:22 +01003628 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3629 if (data) {
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003630 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
3631 struct hci_cp_remote_oob_ext_data_reply cp;
Szymon Janc2763eda2011-03-22 13:12:22 +01003632
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003633 bacpy(&cp.bdaddr, &ev->bdaddr);
3634 memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
3635 memcpy(cp.randomizer192, data->randomizer192,
3636 sizeof(cp.randomizer192));
3637 memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
3638 memcpy(cp.randomizer256, data->randomizer256,
3639 sizeof(cp.randomizer256));
Szymon Janc2763eda2011-03-22 13:12:22 +01003640
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003641 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
3642 sizeof(cp), &cp);
3643 } else {
3644 struct hci_cp_remote_oob_data_reply cp;
3645
3646 bacpy(&cp.bdaddr, &ev->bdaddr);
3647 memcpy(cp.hash, data->hash192, sizeof(cp.hash));
3648 memcpy(cp.randomizer, data->randomizer192,
3649 sizeof(cp.randomizer));
3650
3651 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
3652 sizeof(cp), &cp);
3653 }
Szymon Janc2763eda2011-03-22 13:12:22 +01003654 } else {
3655 struct hci_cp_remote_oob_data_neg_reply cp;
3656
3657 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003658 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
3659 sizeof(cp), &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003660 }
3661
Szymon Jance1ba1f12011-04-06 13:01:59 +02003662unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003663 hci_dev_unlock(hdev);
3664}
3665
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003666static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3667 struct sk_buff *skb)
3668{
3669 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3670 struct hci_conn *hcon, *bredr_hcon;
3671
3672 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3673 ev->status);
3674
3675 hci_dev_lock(hdev);
3676
3677 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3678 if (!hcon) {
3679 hci_dev_unlock(hdev);
3680 return;
3681 }
3682
3683 if (ev->status) {
3684 hci_conn_del(hcon);
3685 hci_dev_unlock(hdev);
3686 return;
3687 }
3688
3689 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3690
3691 hcon->state = BT_CONNECTED;
3692 bacpy(&hcon->dst, &bredr_hcon->dst);
3693
3694 hci_conn_hold(hcon);
3695 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003696 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003697
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003698 hci_conn_add_sysfs(hcon);
3699
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003700 amp_physical_cfm(bredr_hcon, hcon);
3701
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003702 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003703}
3704
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003705static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3706{
3707 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3708 struct hci_conn *hcon;
3709 struct hci_chan *hchan;
3710 struct amp_mgr *mgr;
3711
3712 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3713 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3714 ev->status);
3715
3716 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3717 if (!hcon)
3718 return;
3719
3720 /* Create AMP hchan */
3721 hchan = hci_chan_create(hcon);
3722 if (!hchan)
3723 return;
3724
3725 hchan->handle = le16_to_cpu(ev->handle);
3726
3727 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3728
3729 mgr = hcon->amp_mgr;
3730 if (mgr && mgr->bredr_chan) {
3731 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3732
3733 l2cap_chan_lock(bredr_chan);
3734
3735 bredr_chan->conn->mtu = hdev->block_mtu;
3736 l2cap_logical_cfm(bredr_chan, hchan, 0);
3737 hci_conn_hold(hcon);
3738
3739 l2cap_chan_unlock(bredr_chan);
3740 }
3741}
3742
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003743static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3744 struct sk_buff *skb)
3745{
3746 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3747 struct hci_chan *hchan;
3748
3749 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3750 le16_to_cpu(ev->handle), ev->status);
3751
3752 if (ev->status)
3753 return;
3754
3755 hci_dev_lock(hdev);
3756
3757 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3758 if (!hchan)
3759 goto unlock;
3760
3761 amp_destroy_logical_link(hchan, ev->reason);
3762
3763unlock:
3764 hci_dev_unlock(hdev);
3765}
3766
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003767static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3768 struct sk_buff *skb)
3769{
3770 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3771 struct hci_conn *hcon;
3772
3773 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3774
3775 if (ev->status)
3776 return;
3777
3778 hci_dev_lock(hdev);
3779
3780 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3781 if (hcon) {
3782 hcon->state = BT_CLOSED;
3783 hci_conn_del(hcon);
3784 }
3785
3786 hci_dev_unlock(hdev);
3787}
3788
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003789static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003790{
3791 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3792 struct hci_conn *conn;
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003793 struct smp_irk *irk;
Ville Tervofcd89c02011-02-10 22:38:47 -03003794
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003795 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003796
3797 hci_dev_lock(hdev);
3798
Andre Guedesb47a09b2012-07-27 15:10:15 -03003799 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003800 if (!conn) {
3801 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3802 if (!conn) {
3803 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003804 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003805 }
Andre Guedes29b79882011-05-31 14:20:54 -03003806
3807 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003808
Marcel Holtmann880be4e2013-10-13 07:25:18 -07003809 /* The advertising parameters for own address type
3810 * define which source address and source address
3811 * type this connections has.
3812 */
3813 if (bacmp(&conn->src, BDADDR_ANY)) {
3814 conn->src_type = ADDR_LE_DEV_PUBLIC;
3815 } else {
3816 bacpy(&conn->src, &hdev->static_addr);
3817 conn->src_type = ADDR_LE_DEV_RANDOM;
3818 }
3819
Andre Guedesb9b343d2012-07-27 15:10:11 -03003820 if (ev->role == LE_CONN_ROLE_MASTER) {
3821 conn->out = true;
3822 conn->link_mode |= HCI_LM_MASTER;
3823 }
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02003824
3825 /* If we didn't have a hci_conn object previously
3826 * but we're in master role this must be something
3827 * initiated using a white list. Since white list based
3828 * connections are not "first class citizens" we don't
3829 * have full tracking of them. Therefore, we go ahead
3830 * with a "best effort" approach of determining the
3831 * initiator address based on the HCI_PRIVACY flag.
3832 */
3833 if (conn->out) {
3834 conn->resp_addr_type = ev->bdaddr_type;
3835 bacpy(&conn->resp_addr, &ev->bdaddr);
3836 if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
3837 conn->init_addr_type = ADDR_LE_DEV_RANDOM;
3838 bacpy(&conn->init_addr, &hdev->rpa);
3839 } else {
3840 hci_copy_identity_address(hdev,
3841 &conn->init_addr,
3842 &conn->init_addr_type);
3843 }
3844 } else {
3845 /* Set the responder (our side) address type based on
3846 * the advertising address type.
3847 */
3848 conn->resp_addr_type = hdev->adv_addr_type;
3849 if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM)
3850 bacpy(&conn->resp_addr, &hdev->random_addr);
3851 else
3852 bacpy(&conn->resp_addr, &hdev->bdaddr);
3853
3854 conn->init_addr_type = ev->bdaddr_type;
3855 bacpy(&conn->init_addr, &ev->bdaddr);
3856 }
Johan Hedberg9489eca2014-02-28 17:45:46 +02003857 } else {
3858 cancel_delayed_work(&conn->le_conn_timeout);
Ville Tervob62f3282011-02-10 22:38:50 -03003859 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003860
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003861 /* Ensure that the hci_conn contains the identity address type
3862 * regardless of which address the connection was made with.
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003863 */
Johan Hedberga1f4c312014-02-27 14:05:41 +02003864 hci_copy_identity_address(hdev, &conn->src, &conn->src_type);
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003865
Marcel Holtmannedb4b462014-02-18 15:13:43 -08003866 /* Lookup the identity address from the stored connection
3867 * address and address type.
3868 *
3869 * When establishing connections to an identity address, the
3870 * connection procedure will store the resolvable random
3871 * address first. Now if it can be converted back into the
3872 * identity address, start using the identity address from
3873 * now on.
3874 */
3875 irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003876 if (irk) {
3877 bacpy(&conn->dst, &irk->bdaddr);
3878 conn->dst_type = irk->addr_type;
3879 }
3880
Andre Guedescd17dec2012-07-27 15:10:16 -03003881 if (ev->status) {
Andre Guedes06c053f2014-02-26 20:21:41 -03003882 hci_le_conn_failed(conn, ev->status);
Andre Guedescd17dec2012-07-27 15:10:16 -03003883 goto unlock;
3884 }
3885
Johan Hedbergb644ba32012-01-17 21:48:47 +02003886 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Marcel Holtmann01fdb0f2014-02-18 14:22:19 -08003887 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003888 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003889
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003890 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003891 conn->handle = __le16_to_cpu(ev->handle);
3892 conn->state = BT_CONNECTED;
3893
Jukka Rissanen18722c22013-12-11 17:05:37 +02003894 if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
3895 set_bit(HCI_CONN_6LOWPAN, &conn->flags);
3896
Ville Tervofcd89c02011-02-10 22:38:47 -03003897 hci_conn_add_sysfs(conn);
3898
3899 hci_proto_connect_cfm(conn, ev->status);
3900
Andre Guedesa4790db2014-02-26 20:21:47 -03003901 hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type);
3902
Ville Tervofcd89c02011-02-10 22:38:47 -03003903unlock:
3904 hci_dev_unlock(hdev);
3905}
3906
Andre Guedesa4790db2014-02-26 20:21:47 -03003907/* This function requires the caller holds hdev->lock */
3908static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
3909 u8 addr_type)
3910{
3911 struct hci_conn *conn;
Andre Guedes5b906a82014-02-26 20:21:53 -03003912 struct smp_irk *irk;
3913
3914 /* If this is a resolvable address, we should resolve it and then
3915 * update address and address type variables.
3916 */
3917 irk = hci_get_irk(hdev, addr, addr_type);
3918 if (irk) {
3919 addr = &irk->bdaddr;
3920 addr_type = irk->addr_type;
3921 }
Andre Guedesa4790db2014-02-26 20:21:47 -03003922
3923 if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
3924 return;
3925
3926 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
3927 HCI_AT_NO_BONDING);
3928 if (!IS_ERR(conn))
3929 return;
3930
3931 switch (PTR_ERR(conn)) {
3932 case -EBUSY:
3933 /* If hci_connect() returns -EBUSY it means there is already
3934 * an LE connection attempt going on. Since controllers don't
3935 * support more than one connection attempt at the time, we
3936 * don't consider this an error case.
3937 */
3938 break;
3939 default:
3940 BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
3941 }
3942}
3943
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003944static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003945{
Andre Guedese95beb42011-09-26 20:48:35 -03003946 u8 num_reports = skb->data[0];
3947 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003948 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003949
Andre Guedesa4790db2014-02-26 20:21:47 -03003950 hci_dev_lock(hdev);
3951
Andre Guedese95beb42011-09-26 20:48:35 -03003952 while (num_reports--) {
3953 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003954
Andre Guedesa4790db2014-02-26 20:21:47 -03003955 if (ev->evt_type == LE_ADV_IND ||
3956 ev->evt_type == LE_ADV_DIRECT_IND)
3957 check_pending_le_conn(hdev, &ev->bdaddr,
3958 ev->bdaddr_type);
3959
Andre Guedes3c9e9192012-01-10 18:20:50 -03003960 rssi = ev->data[ev->length];
3961 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003962 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003963
Andre Guedese95beb42011-09-26 20:48:35 -03003964 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003965 }
Andre Guedesa4790db2014-02-26 20:21:47 -03003966
3967 hci_dev_unlock(hdev);
Andre Guedes9aa04c92011-05-26 16:23:51 -03003968}
3969
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003970static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003971{
3972 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3973 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003974 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003975 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003976 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003977
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003978 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003979
3980 hci_dev_lock(hdev);
3981
3982 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003983 if (conn == NULL)
3984 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003985
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08003986 ltk = hci_find_ltk(hdev, ev->ediv, ev->rand, conn->out);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003987 if (ltk == NULL)
3988 goto not_found;
3989
3990 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003991 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003992
3993 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03003994 conn->pending_sec_level = BT_SECURITY_HIGH;
3995 else
3996 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003997
Andre Guedes89cbb4d2013-07-31 16:25:29 -03003998 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003999
4000 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
4001
Claudio Takahasi5981a882013-07-25 16:34:24 -03004002 /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
4003 * temporary key used to encrypt a connection following
4004 * pairing. It is used during the Encrypted Session Setup to
4005 * distribute the keys. Later, security can be re-established
4006 * using a distributed LTK.
4007 */
4008 if (ltk->type == HCI_SMP_STK_SLAVE) {
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03004009 list_del(&ltk->list);
4010 kfree(ltk);
4011 }
4012
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004013 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004014
4015 return;
4016
4017not_found:
4018 neg.handle = ev->handle;
4019 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
4020 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004021}
4022
Gustavo Padovan6039aa72012-05-23 04:04:18 -03004023static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03004024{
4025 struct hci_ev_le_meta *le_ev = (void *) skb->data;
4026
4027 skb_pull(skb, sizeof(*le_ev));
4028
4029 switch (le_ev->subevent) {
4030 case HCI_EV_LE_CONN_COMPLETE:
4031 hci_le_conn_complete_evt(hdev, skb);
4032 break;
4033
Andre Guedes9aa04c92011-05-26 16:23:51 -03004034 case HCI_EV_LE_ADVERTISING_REPORT:
4035 hci_le_adv_report_evt(hdev, skb);
4036 break;
4037
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004038 case HCI_EV_LE_LTK_REQ:
4039 hci_le_ltk_request_evt(hdev, skb);
4040 break;
4041
Ville Tervofcd89c02011-02-10 22:38:47 -03004042 default:
4043 break;
4044 }
4045}
4046
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004047static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
4048{
4049 struct hci_ev_channel_selected *ev = (void *) skb->data;
4050 struct hci_conn *hcon;
4051
4052 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
4053
4054 skb_pull(skb, sizeof(*ev));
4055
4056 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
4057 if (!hcon)
4058 return;
4059
4060 amp_read_loc_assoc_final_data(hdev, hcon);
4061}
4062
Linus Torvalds1da177e2005-04-16 15:20:36 -07004063void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
4064{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004065 struct hci_event_hdr *hdr = (void *) skb->data;
4066 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004067
Johan Hedbergb6ddb632013-04-02 13:34:31 +03004068 hci_dev_lock(hdev);
4069
4070 /* Received events are (currently) only needed when a request is
4071 * ongoing so avoid unnecessary memory allocation.
4072 */
4073 if (hdev->req_status == HCI_REQ_PEND) {
4074 kfree_skb(hdev->recv_evt);
4075 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
4076 }
4077
4078 hci_dev_unlock(hdev);
4079
Linus Torvalds1da177e2005-04-16 15:20:36 -07004080 skb_pull(skb, HCI_EVENT_HDR_SIZE);
4081
Johan Hedberg02350a72013-04-03 21:50:29 +03004082 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02004083 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
4084 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03004085
4086 hci_req_cmd_complete(hdev, opcode, 0);
4087 }
4088
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004089 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004090 case HCI_EV_INQUIRY_COMPLETE:
4091 hci_inquiry_complete_evt(hdev, skb);
4092 break;
4093
4094 case HCI_EV_INQUIRY_RESULT:
4095 hci_inquiry_result_evt(hdev, skb);
4096 break;
4097
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004098 case HCI_EV_CONN_COMPLETE:
4099 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02004100 break;
4101
Linus Torvalds1da177e2005-04-16 15:20:36 -07004102 case HCI_EV_CONN_REQUEST:
4103 hci_conn_request_evt(hdev, skb);
4104 break;
4105
Linus Torvalds1da177e2005-04-16 15:20:36 -07004106 case HCI_EV_DISCONN_COMPLETE:
4107 hci_disconn_complete_evt(hdev, skb);
4108 break;
4109
Linus Torvalds1da177e2005-04-16 15:20:36 -07004110 case HCI_EV_AUTH_COMPLETE:
4111 hci_auth_complete_evt(hdev, skb);
4112 break;
4113
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004114 case HCI_EV_REMOTE_NAME:
4115 hci_remote_name_evt(hdev, skb);
4116 break;
4117
Linus Torvalds1da177e2005-04-16 15:20:36 -07004118 case HCI_EV_ENCRYPT_CHANGE:
4119 hci_encrypt_change_evt(hdev, skb);
4120 break;
4121
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004122 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
4123 hci_change_link_key_complete_evt(hdev, skb);
4124 break;
4125
4126 case HCI_EV_REMOTE_FEATURES:
4127 hci_remote_features_evt(hdev, skb);
4128 break;
4129
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004130 case HCI_EV_CMD_COMPLETE:
4131 hci_cmd_complete_evt(hdev, skb);
4132 break;
4133
4134 case HCI_EV_CMD_STATUS:
4135 hci_cmd_status_evt(hdev, skb);
4136 break;
4137
4138 case HCI_EV_ROLE_CHANGE:
4139 hci_role_change_evt(hdev, skb);
4140 break;
4141
4142 case HCI_EV_NUM_COMP_PKTS:
4143 hci_num_comp_pkts_evt(hdev, skb);
4144 break;
4145
4146 case HCI_EV_MODE_CHANGE:
4147 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004148 break;
4149
4150 case HCI_EV_PIN_CODE_REQ:
4151 hci_pin_code_request_evt(hdev, skb);
4152 break;
4153
4154 case HCI_EV_LINK_KEY_REQ:
4155 hci_link_key_request_evt(hdev, skb);
4156 break;
4157
4158 case HCI_EV_LINK_KEY_NOTIFY:
4159 hci_link_key_notify_evt(hdev, skb);
4160 break;
4161
4162 case HCI_EV_CLOCK_OFFSET:
4163 hci_clock_offset_evt(hdev, skb);
4164 break;
4165
Marcel Holtmanna8746412008-07-14 20:13:46 +02004166 case HCI_EV_PKT_TYPE_CHANGE:
4167 hci_pkt_type_change_evt(hdev, skb);
4168 break;
4169
Marcel Holtmann85a1e932005-08-09 20:28:02 -07004170 case HCI_EV_PSCAN_REP_MODE:
4171 hci_pscan_rep_mode_evt(hdev, skb);
4172 break;
4173
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004174 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
4175 hci_inquiry_result_with_rssi_evt(hdev, skb);
4176 break;
4177
4178 case HCI_EV_REMOTE_EXT_FEATURES:
4179 hci_remote_ext_features_evt(hdev, skb);
4180 break;
4181
4182 case HCI_EV_SYNC_CONN_COMPLETE:
4183 hci_sync_conn_complete_evt(hdev, skb);
4184 break;
4185
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004186 case HCI_EV_EXTENDED_INQUIRY_RESULT:
4187 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004188 break;
4189
Johan Hedberg1c2e0042012-06-08 23:31:13 +08004190 case HCI_EV_KEY_REFRESH_COMPLETE:
4191 hci_key_refresh_complete_evt(hdev, skb);
4192 break;
4193
Marcel Holtmann04936842008-07-14 20:13:48 +02004194 case HCI_EV_IO_CAPA_REQUEST:
4195 hci_io_capa_request_evt(hdev, skb);
4196 break;
4197
Johan Hedberg03b555e2011-01-04 15:40:05 +02004198 case HCI_EV_IO_CAPA_REPLY:
4199 hci_io_capa_reply_evt(hdev, skb);
4200 break;
4201
Johan Hedberga5c29682011-02-19 12:05:57 -03004202 case HCI_EV_USER_CONFIRM_REQUEST:
4203 hci_user_confirm_request_evt(hdev, skb);
4204 break;
4205
Brian Gix1143d452011-11-23 08:28:34 -08004206 case HCI_EV_USER_PASSKEY_REQUEST:
4207 hci_user_passkey_request_evt(hdev, skb);
4208 break;
4209
Johan Hedberg92a25252012-09-06 18:39:26 +03004210 case HCI_EV_USER_PASSKEY_NOTIFY:
4211 hci_user_passkey_notify_evt(hdev, skb);
4212 break;
4213
4214 case HCI_EV_KEYPRESS_NOTIFY:
4215 hci_keypress_notify_evt(hdev, skb);
4216 break;
4217
Marcel Holtmann04936842008-07-14 20:13:48 +02004218 case HCI_EV_SIMPLE_PAIR_COMPLETE:
4219 hci_simple_pair_complete_evt(hdev, skb);
4220 break;
4221
Marcel Holtmann41a96212008-07-14 20:13:48 +02004222 case HCI_EV_REMOTE_HOST_FEATURES:
4223 hci_remote_host_features_evt(hdev, skb);
4224 break;
4225
Ville Tervofcd89c02011-02-10 22:38:47 -03004226 case HCI_EV_LE_META:
4227 hci_le_meta_evt(hdev, skb);
4228 break;
4229
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004230 case HCI_EV_CHANNEL_SELECTED:
4231 hci_chan_selected_evt(hdev, skb);
4232 break;
4233
Szymon Janc2763eda2011-03-22 13:12:22 +01004234 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
4235 hci_remote_oob_data_request_evt(hdev, skb);
4236 break;
4237
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03004238 case HCI_EV_PHY_LINK_COMPLETE:
4239 hci_phy_link_complete_evt(hdev, skb);
4240 break;
4241
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004242 case HCI_EV_LOGICAL_LINK_COMPLETE:
4243 hci_loglink_complete_evt(hdev, skb);
4244 break;
4245
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02004246 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
4247 hci_disconn_loglink_complete_evt(hdev, skb);
4248 break;
4249
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02004250 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
4251 hci_disconn_phylink_complete_evt(hdev, skb);
4252 break;
4253
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02004254 case HCI_EV_NUM_COMP_BLOCKS:
4255 hci_num_comp_blocks_evt(hdev, skb);
4256 break;
4257
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004258 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03004259 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004260 break;
4261 }
4262
4263 kfree_skb(skb);
4264 hdev->stat.evt_rx++;
4265}