blob: 877cee844b9e77e94d606e9cafc543abe6661afe [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
202 hdev->ssp_debug_mode = 0;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200203}
204
205static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
206{
207 __u8 status = *((__u8 *) skb->data);
208 void *sent;
209
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300210 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200211
212 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
213 if (!sent)
214 return;
215
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200216 hci_dev_lock(hdev);
217
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200218 if (test_bit(HCI_MGMT, &hdev->dev_flags))
219 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200220 else if (!status)
221 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200222
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200223 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200224}
225
226static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
227{
228 struct hci_rp_read_local_name *rp = (void *) skb->data;
229
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300230 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200231
232 if (rp->status)
233 return;
234
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200235 if (test_bit(HCI_SETUP, &hdev->dev_flags))
236 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200237}
238
239static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
240{
241 __u8 status = *((__u8 *) skb->data);
242 void *sent;
243
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300244 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200245
246 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
247 if (!sent)
248 return;
249
250 if (!status) {
251 __u8 param = *((__u8 *) sent);
252
253 if (param == AUTH_ENABLED)
254 set_bit(HCI_AUTH, &hdev->flags);
255 else
256 clear_bit(HCI_AUTH, &hdev->flags);
257 }
258
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200259 if (test_bit(HCI_MGMT, &hdev->dev_flags))
260 mgmt_auth_enable_complete(hdev, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200261}
262
263static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
264{
265 __u8 status = *((__u8 *) skb->data);
266 void *sent;
267
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300268 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200269
270 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
271 if (!sent)
272 return;
273
274 if (!status) {
275 __u8 param = *((__u8 *) sent);
276
277 if (param)
278 set_bit(HCI_ENCRYPT, &hdev->flags);
279 else
280 clear_bit(HCI_ENCRYPT, &hdev->flags);
281 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200282}
283
284static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
285{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200286 __u8 param, status = *((__u8 *) skb->data);
287 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200288 void *sent;
289
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300290 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200291
292 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
293 if (!sent)
294 return;
295
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200296 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200297
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200298 hci_dev_lock(hdev);
299
Mikel Astizfa1bd912012-08-09 09:52:29 +0200300 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200301 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200302 hdev->discov_timeout = 0;
303 goto done;
304 }
305
Johan Hedberg0663ca22013-10-02 13:43:14 +0300306 /* We need to ensure that we set this back on if someone changed
307 * the scan mode through a raw HCI socket.
308 */
309 set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
310
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200311 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
312 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200313
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200314 if (param & SCAN_INQUIRY) {
315 set_bit(HCI_ISCAN, &hdev->flags);
316 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200317 mgmt_discoverable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200318 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200319 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200320
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200321 if (param & SCAN_PAGE) {
322 set_bit(HCI_PSCAN, &hdev->flags);
323 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200324 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200325 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200326 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200327
328done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200329 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200330}
331
332static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
333{
334 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
335
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300336 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200337
338 if (rp->status)
339 return;
340
341 memcpy(hdev->dev_class, rp->dev_class, 3);
342
343 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300344 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200345}
346
347static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
348{
349 __u8 status = *((__u8 *) skb->data);
350 void *sent;
351
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300352 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200353
354 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
355 if (!sent)
356 return;
357
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100358 hci_dev_lock(hdev);
359
360 if (status == 0)
361 memcpy(hdev->dev_class, sent, 3);
362
363 if (test_bit(HCI_MGMT, &hdev->dev_flags))
364 mgmt_set_class_of_dev_complete(hdev, sent, status);
365
366 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200367}
368
369static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
370{
371 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200373
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300374 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200375
376 if (rp->status)
377 return;
378
379 setting = __le16_to_cpu(rp->voice_setting);
380
Marcel Holtmannf383f272008-07-14 20:13:47 +0200381 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200382 return;
383
384 hdev->voice_setting = setting;
385
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300386 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200387
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200388 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200390}
391
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300392static void hci_cc_write_voice_setting(struct hci_dev *hdev,
393 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200394{
395 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200396 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 void *sent;
398
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300399 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
Marcel Holtmannf383f272008-07-14 20:13:47 +0200401 if (status)
402 return;
403
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200404 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
405 if (!sent)
406 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
Marcel Holtmannf383f272008-07-14 20:13:47 +0200408 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410 if (hdev->voice_setting == setting)
411 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
Marcel Holtmannf383f272008-07-14 20:13:47 +0200413 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300415 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200416
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200417 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200418 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419}
420
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -0700421static void hci_cc_read_num_supported_iac(struct hci_dev *hdev,
422 struct sk_buff *skb)
423{
424 struct hci_rp_read_num_supported_iac *rp = (void *) skb->data;
425
426 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
427
428 if (rp->status)
429 return;
430
431 hdev->num_iac = rp->num_iac;
432
433 BT_DBG("%s num iac %d", hdev->name, hdev->num_iac);
434}
435
Marcel Holtmann333140b2008-07-14 20:13:48 +0200436static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
437{
438 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300439 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200440
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300441 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200442
Marcel Holtmann333140b2008-07-14 20:13:48 +0200443 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
444 if (!sent)
445 return;
446
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300447 if (!status) {
448 if (sent->mode)
Johan Hedbergcad718e2013-04-17 15:00:51 +0300449 hdev->features[1][0] |= LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300450 else
Johan Hedbergcad718e2013-04-17 15:00:51 +0300451 hdev->features[1][0] &= ~LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300452 }
453
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200454 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300455 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200456 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300457 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200458 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
459 else
460 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
461 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200462}
463
Marcel Holtmanneac83dc2014-01-10 02:07:23 -0800464static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb)
465{
466 u8 status = *((u8 *) skb->data);
467 struct hci_cp_write_sc_support *sent;
468
469 BT_DBG("%s status 0x%2.2x", hdev->name, status);
470
471 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
472 if (!sent)
473 return;
474
475 if (!status) {
476 if (sent->support)
477 hdev->features[1][0] |= LMP_HOST_SC;
478 else
479 hdev->features[1][0] &= ~LMP_HOST_SC;
480 }
481
482 if (test_bit(HCI_MGMT, &hdev->dev_flags))
483 mgmt_sc_enable_complete(hdev, sent->support, status);
484 else if (!status) {
485 if (sent->support)
486 set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
487 else
488 clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
489 }
490}
491
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200492static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
493{
494 struct hci_rp_read_local_version *rp = (void *) skb->data;
495
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300496 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200497
498 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200499 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200500
Marcel Holtmann0d5551f2013-10-18 12:04:50 -0700501 if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
502 hdev->hci_ver = rp->hci_ver;
503 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
504 hdev->lmp_ver = rp->lmp_ver;
505 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
506 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
507 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200508}
509
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300510static void hci_cc_read_local_commands(struct hci_dev *hdev,
511 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200512{
513 struct hci_rp_read_local_commands *rp = (void *) skb->data;
514
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300515 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200516
Marcel Holtmann6a070e62013-10-31 04:54:33 -0700517 if (rp->status)
518 return;
519
520 if (test_bit(HCI_SETUP, &hdev->dev_flags))
Johan Hedberg2177bab2013-03-05 20:37:43 +0200521 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200522}
523
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300524static void hci_cc_read_local_features(struct hci_dev *hdev,
525 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200526{
527 struct hci_rp_read_local_features *rp = (void *) skb->data;
528
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300529 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200530
531 if (rp->status)
532 return;
533
534 memcpy(hdev->features, rp->features, 8);
535
536 /* Adjust default settings according to features
537 * supported by device. */
538
Johan Hedbergcad718e2013-04-17 15:00:51 +0300539 if (hdev->features[0][0] & LMP_3SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200540 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
541
Johan Hedbergcad718e2013-04-17 15:00:51 +0300542 if (hdev->features[0][0] & LMP_5SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200543 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
544
Johan Hedbergcad718e2013-04-17 15:00:51 +0300545 if (hdev->features[0][1] & LMP_HV2) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200546 hdev->pkt_type |= (HCI_HV2);
547 hdev->esco_type |= (ESCO_HV2);
548 }
549
Johan Hedbergcad718e2013-04-17 15:00:51 +0300550 if (hdev->features[0][1] & LMP_HV3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200551 hdev->pkt_type |= (HCI_HV3);
552 hdev->esco_type |= (ESCO_HV3);
553 }
554
Andre Guedes45db810f2012-07-24 15:03:49 -0300555 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200556 hdev->esco_type |= (ESCO_EV3);
557
Johan Hedbergcad718e2013-04-17 15:00:51 +0300558 if (hdev->features[0][4] & LMP_EV4)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200559 hdev->esco_type |= (ESCO_EV4);
560
Johan Hedbergcad718e2013-04-17 15:00:51 +0300561 if (hdev->features[0][4] & LMP_EV5)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200562 hdev->esco_type |= (ESCO_EV5);
563
Johan Hedbergcad718e2013-04-17 15:00:51 +0300564 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100565 hdev->esco_type |= (ESCO_2EV3);
566
Johan Hedbergcad718e2013-04-17 15:00:51 +0300567 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100568 hdev->esco_type |= (ESCO_3EV3);
569
Johan Hedbergcad718e2013-04-17 15:00:51 +0300570 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100571 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200572}
573
Andre Guedes971e3a42011-06-30 19:20:52 -0300574static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300575 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300576{
577 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
578
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300579 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300580
581 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200582 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300583
Marcel Holtmann57af75a2013-10-18 12:04:47 -0700584 if (hdev->max_page < rp->max_page)
585 hdev->max_page = rp->max_page;
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300586
Johan Hedbergcad718e2013-04-17 15:00:51 +0300587 if (rp->page < HCI_MAX_PAGES)
588 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300589}
590
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200591static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300592 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200593{
594 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
595
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300596 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200597
Johan Hedberg42c6b122013-03-05 20:37:49 +0200598 if (!rp->status)
599 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200600}
601
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200602static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
603{
604 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
605
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300606 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200607
608 if (rp->status)
609 return;
610
611 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
612 hdev->sco_mtu = rp->sco_mtu;
613 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
614 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
615
616 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
617 hdev->sco_mtu = 64;
618 hdev->sco_pkts = 8;
619 }
620
621 hdev->acl_cnt = hdev->acl_pkts;
622 hdev->sco_cnt = hdev->sco_pkts;
623
Gustavo Padovan807deac2012-05-17 00:36:24 -0300624 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
625 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200626}
627
628static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
629{
630 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
631
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300632 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200633
634 if (!rp->status)
635 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200636}
637
Johan Hedbergf332ec62013-03-15 17:07:11 -0500638static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
639 struct sk_buff *skb)
640{
641 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
642
643 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
644
645 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
646 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
647 hdev->page_scan_window = __le16_to_cpu(rp->window);
648 }
649}
650
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500651static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
652 struct sk_buff *skb)
653{
654 u8 status = *((u8 *) skb->data);
655 struct hci_cp_write_page_scan_activity *sent;
656
657 BT_DBG("%s status 0x%2.2x", hdev->name, status);
658
659 if (status)
660 return;
661
662 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
663 if (!sent)
664 return;
665
666 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
667 hdev->page_scan_window = __le16_to_cpu(sent->window);
668}
669
Johan Hedbergf332ec62013-03-15 17:07:11 -0500670static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
671 struct sk_buff *skb)
672{
673 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
674
675 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
676
677 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
678 hdev->page_scan_type = rp->type;
679}
680
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500681static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
682 struct sk_buff *skb)
683{
684 u8 status = *((u8 *) skb->data);
685 u8 *type;
686
687 BT_DBG("%s status 0x%2.2x", hdev->name, status);
688
689 if (status)
690 return;
691
692 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
693 if (type)
694 hdev->page_scan_type = *type;
695}
696
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200697static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300698 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200699{
700 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
701
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300702 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200703
704 if (rp->status)
705 return;
706
707 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
708 hdev->block_len = __le16_to_cpu(rp->block_len);
709 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
710
711 hdev->block_cnt = hdev->num_blocks;
712
713 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300714 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200715}
716
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300717static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300718 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300719{
720 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
721
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300722 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300723
724 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300725 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300726
727 hdev->amp_status = rp->amp_status;
728 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
729 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
730 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
731 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
732 hdev->amp_type = rp->amp_type;
733 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
734 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
735 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
736 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
737
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300738a2mp_rsp:
739 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300740}
741
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300742static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
743 struct sk_buff *skb)
744{
745 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
746 struct amp_assoc *assoc = &hdev->loc_assoc;
747 size_t rem_len, frag_len;
748
749 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
750
751 if (rp->status)
752 goto a2mp_rsp;
753
754 frag_len = skb->len - sizeof(*rp);
755 rem_len = __le16_to_cpu(rp->rem_len);
756
757 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300758 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300759
760 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
761 assoc->offset += frag_len;
762
763 /* Read other fragments */
764 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
765
766 return;
767 }
768
769 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
770 assoc->len = assoc->offset + rem_len;
771 assoc->offset = 0;
772
773a2mp_rsp:
774 /* Send A2MP Rsp when all fragments are received */
775 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300776 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300777}
778
Johan Hedbergd5859e22011-01-25 01:19:58 +0200779static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300780 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200781{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700782 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200783
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300784 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200785
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700786 if (!rp->status)
787 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200788}
789
Johan Hedberg980e1a52011-01-22 06:10:07 +0200790static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
791{
792 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
793 struct hci_cp_pin_code_reply *cp;
794 struct hci_conn *conn;
795
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300796 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200797
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200798 hci_dev_lock(hdev);
799
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200800 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200801 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200802
Mikel Astizfa1bd912012-08-09 09:52:29 +0200803 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200804 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200805
806 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
807 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200808 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200809
810 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
811 if (conn)
812 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200813
814unlock:
815 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200816}
817
818static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
819{
820 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
821
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300822 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200823
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200824 hci_dev_lock(hdev);
825
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200826 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200827 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300828 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200829
830 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200831}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200832
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300833static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
834 struct sk_buff *skb)
835{
836 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
837
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300838 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300839
840 if (rp->status)
841 return;
842
843 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
844 hdev->le_pkts = rp->le_max_pkt;
845
846 hdev->le_cnt = hdev->le_pkts;
847
848 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300849}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200850
Johan Hedberg60e77322013-01-22 14:01:59 +0200851static void hci_cc_le_read_local_features(struct hci_dev *hdev,
852 struct sk_buff *skb)
853{
854 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
855
856 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
857
858 if (!rp->status)
859 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200860}
861
Johan Hedberg8fa19092012-10-19 20:57:49 +0300862static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
863 struct sk_buff *skb)
864{
865 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
866
867 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
868
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500869 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300870 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300871}
872
Johan Hedberga5c29682011-02-19 12:05:57 -0300873static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
874{
875 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
876
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300877 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300878
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200879 hci_dev_lock(hdev);
880
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200881 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300882 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
883 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200884
885 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300886}
887
888static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300889 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300890{
891 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
892
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300893 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300894
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200895 hci_dev_lock(hdev);
896
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200897 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200898 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300899 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200900
901 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300902}
903
Brian Gix1143d452011-11-23 08:28:34 -0800904static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
905{
906 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
907
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300908 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800909
910 hci_dev_lock(hdev);
911
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200912 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200913 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300914 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800915
916 hci_dev_unlock(hdev);
917}
918
919static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300920 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800921{
922 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
923
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300924 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800925
926 hci_dev_lock(hdev);
927
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200928 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800929 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300930 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800931
932 hci_dev_unlock(hdev);
933}
934
Marcel Holtmann4d2d2792014-01-10 02:07:26 -0800935static void hci_cc_read_local_oob_data(struct hci_dev *hdev,
936 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100937{
938 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
939
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300940 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100941
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200942 hci_dev_lock(hdev);
Marcel Holtmann4d2d2792014-01-10 02:07:26 -0800943 mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->randomizer,
944 NULL, NULL, rp->status);
945 hci_dev_unlock(hdev);
946}
947
948static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev,
949 struct sk_buff *skb)
950{
951 struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data;
952
953 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
954
955 hci_dev_lock(hdev);
956 mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->randomizer192,
957 rp->hash256, rp->randomizer256,
958 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200959 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100960}
961
Marcel Holtmann7a4cd512014-02-19 19:52:13 -0800962
963static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb)
964{
965 __u8 status = *((__u8 *) skb->data);
966 bdaddr_t *sent;
967
968 BT_DBG("%s status 0x%2.2x", hdev->name, status);
969
970 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
971 if (!sent)
972 return;
973
974 hci_dev_lock(hdev);
975
976 if (!status)
977 bacpy(&hdev->random_addr, sent);
978
979 hci_dev_unlock(hdev);
980}
981
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100982static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
983{
984 __u8 *sent, status = *((__u8 *) skb->data);
985
986 BT_DBG("%s status 0x%2.2x", hdev->name, status);
987
988 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
989 if (!sent)
990 return;
991
992 hci_dev_lock(hdev);
993
Johan Hedberg778b2352014-02-24 14:52:17 +0200994 if (!status)
995 mgmt_advertising(hdev, *sent);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100996
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500997 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100998}
999
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001000static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001001 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001002{
1003 struct hci_cp_le_set_scan_enable *cp;
1004 __u8 status = *((__u8 *) skb->data);
1005
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001006 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001007
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001008 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1009 if (!cp)
1010 return;
1011
Andre Guedes3fd319b2013-04-30 15:29:36 -03001012 if (status)
1013 return;
1014
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001015 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -03001016 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -03001017 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001018 break;
1019
Andre Guedes76a388b2013-04-04 20:21:02 -03001020 case LE_SCAN_DISABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -03001021 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001022 break;
1023
1024 default:
1025 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1026 break;
Andre Guedes35815082011-05-26 16:23:53 -03001027 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001028}
1029
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001030static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
1031 struct sk_buff *skb)
1032{
1033 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
1034
1035 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
1036
1037 if (!rp->status)
1038 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001039}
1040
Johan Hedberg9b008c02013-01-22 14:02:01 +02001041static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
1042 struct sk_buff *skb)
1043{
1044 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
1045
1046 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1047
1048 if (!rp->status)
1049 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +02001050}
1051
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001052static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1053 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001054{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001055 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001056 __u8 status = *((__u8 *) skb->data);
1057
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001058 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001059
Johan Hedberg06199cf2012-02-22 16:37:11 +02001060 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001061 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001062 return;
1063
Johan Hedberg8f984df2012-02-28 01:07:22 +02001064 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001065 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001066 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001067 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1068 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001069 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001070 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001071 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001072 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001073
1074 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001075 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001076 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001077 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001078 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001079}
1080
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001081static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1082 struct sk_buff *skb)
1083{
1084 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1085
1086 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1087 hdev->name, rp->status, rp->phy_handle);
1088
1089 if (rp->status)
1090 return;
1091
1092 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1093}
1094
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001095static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001096{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001097 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001098
1099 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001100 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001101 return;
1102 }
1103
Andre Guedes89352e72011-11-04 14:16:53 -03001104 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001105}
1106
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001107static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001109 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001112 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001113
1114 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115 if (!cp)
1116 return;
1117
1118 hci_dev_lock(hdev);
1119
1120 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1121
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001122 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123
1124 if (status) {
1125 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001126 if (status != 0x0c || conn->attempt > 2) {
1127 conn->state = BT_CLOSED;
1128 hci_proto_connect_cfm(conn, status);
1129 hci_conn_del(conn);
1130 } else
1131 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132 }
1133 } else {
1134 if (!conn) {
1135 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1136 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001137 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138 conn->link_mode |= HCI_LM_MASTER;
1139 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001140 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 }
1142 }
1143
1144 hci_dev_unlock(hdev);
1145}
1146
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001147static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001149 struct hci_cp_add_sco *cp;
1150 struct hci_conn *acl, *sco;
1151 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001153 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001154
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001155 if (!status)
1156 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001158 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1159 if (!cp)
1160 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001162 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001164 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001165
1166 hci_dev_lock(hdev);
1167
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001168 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001169 if (acl) {
1170 sco = acl->link;
1171 if (sco) {
1172 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001173
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001174 hci_proto_connect_cfm(sco, status);
1175 hci_conn_del(sco);
1176 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001177 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001178
1179 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180}
1181
Marcel Holtmannf8558552008-07-14 20:13:49 +02001182static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1183{
1184 struct hci_cp_auth_requested *cp;
1185 struct hci_conn *conn;
1186
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001187 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001188
1189 if (!status)
1190 return;
1191
1192 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1193 if (!cp)
1194 return;
1195
1196 hci_dev_lock(hdev);
1197
1198 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1199 if (conn) {
1200 if (conn->state == BT_CONFIG) {
1201 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001202 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001203 }
1204 }
1205
1206 hci_dev_unlock(hdev);
1207}
1208
1209static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1210{
1211 struct hci_cp_set_conn_encrypt *cp;
1212 struct hci_conn *conn;
1213
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001214 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001215
1216 if (!status)
1217 return;
1218
1219 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1220 if (!cp)
1221 return;
1222
1223 hci_dev_lock(hdev);
1224
1225 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1226 if (conn) {
1227 if (conn->state == BT_CONFIG) {
1228 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001229 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001230 }
1231 }
1232
1233 hci_dev_unlock(hdev);
1234}
1235
Johan Hedberg127178d2010-11-18 22:22:29 +02001236static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001237 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001238{
Johan Hedberg392599b2010-11-18 22:22:28 +02001239 if (conn->state != BT_CONFIG || !conn->out)
1240 return 0;
1241
Johan Hedberg765c2a92011-01-19 12:06:52 +05301242 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001243 return 0;
1244
1245 /* Only request authentication for SSP connections or non-SSP
Johan Hedberg264b8b42014-01-08 16:40:39 +02001246 * devices with sec_level MEDIUM or HIGH or if MITM protection
1247 * is requested.
1248 */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001249 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
Johan Hedberg264b8b42014-01-08 16:40:39 +02001250 conn->pending_sec_level != BT_SECURITY_HIGH &&
1251 conn->pending_sec_level != BT_SECURITY_MEDIUM)
Johan Hedberg392599b2010-11-18 22:22:28 +02001252 return 0;
1253
Johan Hedberg392599b2010-11-18 22:22:28 +02001254 return 1;
1255}
1256
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001257static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001258 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001259{
1260 struct hci_cp_remote_name_req cp;
1261
1262 memset(&cp, 0, sizeof(cp));
1263
1264 bacpy(&cp.bdaddr, &e->data.bdaddr);
1265 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1266 cp.pscan_mode = e->data.pscan_mode;
1267 cp.clock_offset = e->data.clock_offset;
1268
1269 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1270}
1271
Johan Hedbergb644ba32012-01-17 21:48:47 +02001272static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001273{
1274 struct discovery_state *discov = &hdev->discovery;
1275 struct inquiry_entry *e;
1276
Johan Hedbergb644ba32012-01-17 21:48:47 +02001277 if (list_empty(&discov->resolve))
1278 return false;
1279
1280 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001281 if (!e)
1282 return false;
1283
Johan Hedbergb644ba32012-01-17 21:48:47 +02001284 if (hci_resolve_name(hdev, e) == 0) {
1285 e->name_state = NAME_PENDING;
1286 return true;
1287 }
1288
1289 return false;
1290}
1291
1292static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001293 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001294{
1295 struct discovery_state *discov = &hdev->discovery;
1296 struct inquiry_entry *e;
1297
1298 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001299 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1300 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001301
1302 if (discov->state == DISCOVERY_STOPPED)
1303 return;
1304
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001305 if (discov->state == DISCOVERY_STOPPING)
1306 goto discov_complete;
1307
1308 if (discov->state != DISCOVERY_RESOLVING)
1309 return;
1310
1311 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001312 /* If the device was not found in a list of found devices names of which
1313 * are pending. there is no need to continue resolving a next name as it
1314 * will be done upon receiving another Remote Name Request Complete
1315 * Event */
1316 if (!e)
1317 return;
1318
1319 list_del(&e->list);
1320 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001321 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001322 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1323 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001324 } else {
1325 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001326 }
1327
Johan Hedbergb644ba32012-01-17 21:48:47 +02001328 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001329 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001330
1331discov_complete:
1332 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1333}
1334
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001335static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1336{
Johan Hedberg127178d2010-11-18 22:22:29 +02001337 struct hci_cp_remote_name_req *cp;
1338 struct hci_conn *conn;
1339
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001340 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001341
1342 /* If successful wait for the name req complete event before
1343 * checking for the need to do authentication */
1344 if (!status)
1345 return;
1346
1347 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1348 if (!cp)
1349 return;
1350
1351 hci_dev_lock(hdev);
1352
1353 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001354
1355 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1356 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1357
Johan Hedberg79c6c702011-04-28 11:28:55 -07001358 if (!conn)
1359 goto unlock;
1360
1361 if (!hci_outgoing_auth_needed(hdev, conn))
1362 goto unlock;
1363
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001364 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001365 struct hci_cp_auth_requested auth_cp;
1366
1367 auth_cp.handle = __cpu_to_le16(conn->handle);
1368 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1369 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001370 }
1371
Johan Hedberg79c6c702011-04-28 11:28:55 -07001372unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001373 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001374}
1375
Marcel Holtmann769be972008-07-14 20:13:49 +02001376static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1377{
1378 struct hci_cp_read_remote_features *cp;
1379 struct hci_conn *conn;
1380
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001381 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001382
1383 if (!status)
1384 return;
1385
1386 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1387 if (!cp)
1388 return;
1389
1390 hci_dev_lock(hdev);
1391
1392 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1393 if (conn) {
1394 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001395 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001396 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001397 }
1398 }
1399
1400 hci_dev_unlock(hdev);
1401}
1402
1403static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1404{
1405 struct hci_cp_read_remote_ext_features *cp;
1406 struct hci_conn *conn;
1407
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001408 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001409
1410 if (!status)
1411 return;
1412
1413 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1414 if (!cp)
1415 return;
1416
1417 hci_dev_lock(hdev);
1418
1419 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1420 if (conn) {
1421 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001422 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001423 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001424 }
1425 }
1426
1427 hci_dev_unlock(hdev);
1428}
1429
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001430static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1431{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001432 struct hci_cp_setup_sync_conn *cp;
1433 struct hci_conn *acl, *sco;
1434 __u16 handle;
1435
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001436 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001437
1438 if (!status)
1439 return;
1440
1441 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1442 if (!cp)
1443 return;
1444
1445 handle = __le16_to_cpu(cp->handle);
1446
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001447 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001448
1449 hci_dev_lock(hdev);
1450
1451 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001452 if (acl) {
1453 sco = acl->link;
1454 if (sco) {
1455 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001456
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001457 hci_proto_connect_cfm(sco, status);
1458 hci_conn_del(sco);
1459 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001460 }
1461
1462 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001463}
1464
1465static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1466{
1467 struct hci_cp_sniff_mode *cp;
1468 struct hci_conn *conn;
1469
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001470 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001471
1472 if (!status)
1473 return;
1474
1475 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1476 if (!cp)
1477 return;
1478
1479 hci_dev_lock(hdev);
1480
1481 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001482 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001483 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001484
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001485 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001486 hci_sco_setup(conn, status);
1487 }
1488
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001489 hci_dev_unlock(hdev);
1490}
1491
1492static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1493{
1494 struct hci_cp_exit_sniff_mode *cp;
1495 struct hci_conn *conn;
1496
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001497 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001498
1499 if (!status)
1500 return;
1501
1502 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1503 if (!cp)
1504 return;
1505
1506 hci_dev_lock(hdev);
1507
1508 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001509 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001510 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001511
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001512 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001513 hci_sco_setup(conn, status);
1514 }
1515
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001516 hci_dev_unlock(hdev);
1517}
1518
Johan Hedberg88c3df12012-02-09 14:27:38 +02001519static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1520{
1521 struct hci_cp_disconnect *cp;
1522 struct hci_conn *conn;
1523
1524 if (!status)
1525 return;
1526
1527 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1528 if (!cp)
1529 return;
1530
1531 hci_dev_lock(hdev);
1532
1533 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1534 if (conn)
1535 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001536 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001537
1538 hci_dev_unlock(hdev);
1539}
1540
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001541static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1542{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001543 struct hci_cp_create_phy_link *cp;
1544
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001545 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001546
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001547 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1548 if (!cp)
1549 return;
1550
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001551 hci_dev_lock(hdev);
1552
1553 if (status) {
1554 struct hci_conn *hcon;
1555
1556 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1557 if (hcon)
1558 hci_conn_del(hcon);
1559 } else {
1560 amp_write_remote_assoc(hdev, cp->phy_handle);
1561 }
1562
1563 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001564}
1565
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001566static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1567{
1568 struct hci_cp_accept_phy_link *cp;
1569
1570 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1571
1572 if (status)
1573 return;
1574
1575 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1576 if (!cp)
1577 return;
1578
1579 amp_write_remote_assoc(hdev, cp->phy_handle);
1580}
1581
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001582static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001583{
1584 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001585 struct discovery_state *discov = &hdev->discovery;
1586 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001587
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001588 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001589
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001590 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001591
1592 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1593 return;
1594
Andre Guedes3e13fa12013-03-27 20:04:56 -03001595 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1596 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1597
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001598 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001599 return;
1600
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001601 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001602
Andre Guedes343f9352012-02-17 20:39:37 -03001603 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001604 goto unlock;
1605
1606 if (list_empty(&discov->resolve)) {
1607 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1608 goto unlock;
1609 }
1610
1611 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1612 if (e && hci_resolve_name(hdev, e) == 0) {
1613 e->name_state = NAME_PENDING;
1614 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1615 } else {
1616 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1617 }
1618
1619unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001620 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001621}
1622
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001623static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001625 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001626 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 int num_rsp = *((__u8 *) skb->data);
1628
1629 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1630
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001631 if (!num_rsp)
1632 return;
1633
Andre Guedes1519cc12012-03-21 00:03:38 -03001634 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1635 return;
1636
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001638
Johan Hedberge17acd42011-03-30 23:57:16 +03001639 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001640 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001641
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642 bacpy(&data.bdaddr, &info->bdaddr);
1643 data.pscan_rep_mode = info->pscan_rep_mode;
1644 data.pscan_period_mode = info->pscan_period_mode;
1645 data.pscan_mode = info->pscan_mode;
1646 memcpy(data.dev_class, info->dev_class, 3);
1647 data.clock_offset = info->clock_offset;
1648 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001649 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001650
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001651 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001652 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001653 info->dev_class, 0, !name_known, ssp, NULL,
1654 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001656
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657 hci_dev_unlock(hdev);
1658}
1659
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001660static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001662 struct hci_ev_conn_complete *ev = (void *) skb->data;
1663 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001665 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001666
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001668
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001669 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001670 if (!conn) {
1671 if (ev->link_type != SCO_LINK)
1672 goto unlock;
1673
1674 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1675 if (!conn)
1676 goto unlock;
1677
1678 conn->type = SCO_LINK;
1679 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001680
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001681 if (!ev->status) {
1682 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001683
1684 if (conn->type == ACL_LINK) {
1685 conn->state = BT_CONFIG;
1686 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001687
1688 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1689 !hci_find_link_key(hdev, &ev->bdaddr))
1690 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1691 else
1692 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001693 } else
1694 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001695
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001696 hci_conn_add_sysfs(conn);
1697
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001698 if (test_bit(HCI_AUTH, &hdev->flags))
1699 conn->link_mode |= HCI_LM_AUTH;
1700
1701 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1702 conn->link_mode |= HCI_LM_ENCRYPT;
1703
1704 /* Get remote features */
1705 if (conn->type == ACL_LINK) {
1706 struct hci_cp_read_remote_features cp;
1707 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001708 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001709 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001710 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001711
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001712 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001713 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001714 struct hci_cp_change_conn_ptype cp;
1715 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001716 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001717 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1718 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001719 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001720 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001721 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001722 if (conn->type == ACL_LINK)
Marcel Holtmann64c7b772014-02-18 14:22:20 -08001723 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001724 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001725 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001726
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001727 if (conn->type == ACL_LINK)
1728 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001729
Marcel Holtmann769be972008-07-14 20:13:49 +02001730 if (ev->status) {
1731 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001732 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001733 } else if (ev->link_type != ACL_LINK)
1734 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001735
1736unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001738
1739 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740}
1741
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001742static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001744 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001746 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001748 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001749 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001751 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1752 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753
Szymon Janc138d22e2011-02-17 16:44:23 +01001754 if ((mask & HCI_LM_ACCEPT) &&
Marcel Holtmannb9ee0a72013-10-17 17:24:13 -07001755 !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001757 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759
1760 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001761
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001762 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1763 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001764 memcpy(ie->data.dev_class, ev->dev_class, 3);
1765
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001766 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1767 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001769 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1770 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001771 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 hci_dev_unlock(hdev);
1773 return;
1774 }
1775 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001776
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001778
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 hci_dev_unlock(hdev);
1780
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001781 if (ev->link_type == ACL_LINK ||
1782 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001783 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001784 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001786 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001788 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1789 cp.role = 0x00; /* Become master */
1790 else
1791 cp.role = 0x01; /* Remain slave */
1792
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001793 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1794 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001795 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001796 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001797 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001798
1799 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001800 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001801
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001802 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1803 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1804 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001805 cp.content_format = cpu_to_le16(hdev->voice_setting);
1806 cp.retrans_effort = 0xff;
1807
1808 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001809 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001810 } else {
1811 conn->state = BT_CONNECT2;
1812 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001813 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 } else {
1815 /* Connection rejected */
1816 struct hci_cp_reject_conn_req cp;
1817
1818 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001819 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001820 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821 }
1822}
1823
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001824static u8 hci_to_mgmt_reason(u8 err)
1825{
1826 switch (err) {
1827 case HCI_ERROR_CONNECTION_TIMEOUT:
1828 return MGMT_DEV_DISCONN_TIMEOUT;
1829 case HCI_ERROR_REMOTE_USER_TERM:
1830 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1831 case HCI_ERROR_REMOTE_POWER_OFF:
1832 return MGMT_DEV_DISCONN_REMOTE;
1833 case HCI_ERROR_LOCAL_HOST_TERM:
1834 return MGMT_DEV_DISCONN_LOCAL_HOST;
1835 default:
1836 return MGMT_DEV_DISCONN_UNKNOWN;
1837 }
1838}
1839
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001840static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001842 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Andre Guedesabf54a52013-11-07 17:36:09 -03001843 u8 reason = hci_to_mgmt_reason(ev->reason);
Marcel Holtmann04837f62006-07-03 10:02:33 +02001844 struct hci_conn *conn;
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02001845 bool mgmt_connected;
Andre Guedes38462202013-11-07 17:36:10 -03001846 u8 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001848 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 hci_dev_lock(hdev);
1851
Marcel Holtmann04837f62006-07-03 10:02:33 +02001852 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001853 if (!conn)
1854 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001855
Andre Guedesabf54a52013-11-07 17:36:09 -03001856 if (ev->status) {
1857 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1858 conn->dst_type, ev->status);
1859 goto unlock;
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001860 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001861
Andre Guedes38462202013-11-07 17:36:10 -03001862 conn->state = BT_CLOSED;
1863
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02001864 mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
1865 mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
1866 reason, mgmt_connected);
Andre Guedesabf54a52013-11-07 17:36:09 -03001867
Andre Guedes38462202013-11-07 17:36:10 -03001868 if (conn->type == ACL_LINK && conn->flush_key)
1869 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg22102462013-10-05 12:01:06 +02001870
Andre Guedes38462202013-11-07 17:36:10 -03001871 type = conn->type;
Johan Hedberg22102462013-10-05 12:01:06 +02001872
Andre Guedes38462202013-11-07 17:36:10 -03001873 hci_proto_disconn_cfm(conn, ev->reason);
1874 hci_conn_del(conn);
1875
1876 /* Re-enable advertising if necessary, since it might
1877 * have been disabled by the connection. From the
1878 * HCI_LE_Set_Advertise_Enable command description in
1879 * the core specification (v4.0):
1880 * "The Controller shall continue advertising until the Host
1881 * issues an LE_Set_Advertise_Enable command with
1882 * Advertising_Enable set to 0x00 (Advertising is disabled)
1883 * or until a connection is created or until the Advertising
1884 * is timed out due to Directed Advertising."
1885 */
1886 if (type == LE_LINK)
1887 mgmt_reenable_advertising(hdev);
Johan Hedbergf7520542011-01-20 12:34:39 +02001888
1889unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 hci_dev_unlock(hdev);
1891}
1892
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001893static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001894{
1895 struct hci_ev_auth_complete *ev = (void *) skb->data;
1896 struct hci_conn *conn;
1897
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001898 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001899
1900 hci_dev_lock(hdev);
1901
1902 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001903 if (!conn)
1904 goto unlock;
1905
1906 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001907 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001908 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001909 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001910 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001911 conn->link_mode |= HCI_LM_AUTH;
1912 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001913 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001914 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001915 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001916 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001917 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001918
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001919 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1920 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001921
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001922 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001923 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001924 struct hci_cp_set_conn_encrypt cp;
1925 cp.handle = ev->handle;
1926 cp.encrypt = 0x01;
1927 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001928 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001929 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001930 conn->state = BT_CONNECTED;
1931 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001932 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001933 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001934 } else {
1935 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001936
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001937 hci_conn_hold(conn);
1938 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001939 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001940 }
1941
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001942 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001943 if (!ev->status) {
1944 struct hci_cp_set_conn_encrypt cp;
1945 cp.handle = ev->handle;
1946 cp.encrypt = 0x01;
1947 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001948 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001949 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001950 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001951 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001952 }
1953 }
1954
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001955unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001956 hci_dev_unlock(hdev);
1957}
1958
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001959static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001960{
Johan Hedberg127178d2010-11-18 22:22:29 +02001961 struct hci_ev_remote_name *ev = (void *) skb->data;
1962 struct hci_conn *conn;
1963
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001964 BT_DBG("%s", hdev->name);
1965
1966 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001967
1968 hci_dev_lock(hdev);
1969
1970 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001971
1972 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1973 goto check_auth;
1974
1975 if (ev->status == 0)
1976 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001977 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001978 else
1979 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1980
1981check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001982 if (!conn)
1983 goto unlock;
1984
1985 if (!hci_outgoing_auth_needed(hdev, conn))
1986 goto unlock;
1987
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001988 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001989 struct hci_cp_auth_requested cp;
1990 cp.handle = __cpu_to_le16(conn->handle);
1991 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1992 }
1993
Johan Hedberg79c6c702011-04-28 11:28:55 -07001994unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001995 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001996}
1997
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001998static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001999{
2000 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2001 struct hci_conn *conn;
2002
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002003 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002004
2005 hci_dev_lock(hdev);
2006
2007 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002008 if (!conn)
2009 goto unlock;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002010
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002011 if (!ev->status) {
2012 if (ev->encrypt) {
2013 /* Encryption implies authentication */
2014 conn->link_mode |= HCI_LM_AUTH;
2015 conn->link_mode |= HCI_LM_ENCRYPT;
2016 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002017
Marcel Holtmann914a6ff2014-02-01 11:52:02 -08002018 /* P-256 authentication key implies FIPS */
2019 if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
2020 conn->link_mode |= HCI_LM_FIPS;
2021
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002022 if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
2023 conn->type == LE_LINK)
2024 set_bit(HCI_CONN_AES_CCM, &conn->flags);
2025 } else {
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002026 conn->link_mode &= ~HCI_LM_ENCRYPT;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002027 clear_bit(HCI_CONN_AES_CCM, &conn->flags);
2028 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002029 }
2030
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002031 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2032
2033 if (ev->status && conn->state == BT_CONNECTED) {
2034 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
2035 hci_conn_drop(conn);
2036 goto unlock;
2037 }
2038
2039 if (conn->state == BT_CONFIG) {
2040 if (!ev->status)
2041 conn->state = BT_CONNECTED;
2042
2043 hci_proto_connect_cfm(conn, ev->status);
2044 hci_conn_drop(conn);
2045 } else
2046 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
2047
Gustavo Padovana7d77232012-05-13 03:20:07 -03002048unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002049 hci_dev_unlock(hdev);
2050}
2051
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002052static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2053 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002054{
2055 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2056 struct hci_conn *conn;
2057
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002058 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002059
2060 hci_dev_lock(hdev);
2061
2062 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2063 if (conn) {
2064 if (!ev->status)
2065 conn->link_mode |= HCI_LM_SECURE;
2066
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002067 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002068
2069 hci_key_change_cfm(conn, ev->status);
2070 }
2071
2072 hci_dev_unlock(hdev);
2073}
2074
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002075static void hci_remote_features_evt(struct hci_dev *hdev,
2076 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002077{
2078 struct hci_ev_remote_features *ev = (void *) skb->data;
2079 struct hci_conn *conn;
2080
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002081 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002082
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002083 hci_dev_lock(hdev);
2084
2085 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002086 if (!conn)
2087 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002088
Johan Hedbergccd556f2010-11-10 17:11:51 +02002089 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002090 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002091
2092 if (conn->state != BT_CONFIG)
2093 goto unlock;
2094
2095 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2096 struct hci_cp_read_remote_ext_features cp;
2097 cp.handle = ev->handle;
2098 cp.page = 0x01;
2099 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002100 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002101 goto unlock;
2102 }
2103
Johan Hedberg671267b2012-05-12 16:11:50 -03002104 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002105 struct hci_cp_remote_name_req cp;
2106 memset(&cp, 0, sizeof(cp));
2107 bacpy(&cp.bdaddr, &conn->dst);
2108 cp.pscan_rep_mode = 0x02;
2109 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002110 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2111 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002112 conn->dst_type, 0, NULL, 0,
2113 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002114
Johan Hedberg127178d2010-11-18 22:22:29 +02002115 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002116 conn->state = BT_CONNECTED;
2117 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002118 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002119 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002120
Johan Hedbergccd556f2010-11-10 17:11:51 +02002121unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002122 hci_dev_unlock(hdev);
2123}
2124
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002125static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002126{
2127 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002128 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002129 __u16 opcode;
2130
2131 skb_pull(skb, sizeof(*ev));
2132
2133 opcode = __le16_to_cpu(ev->opcode);
2134
2135 switch (opcode) {
2136 case HCI_OP_INQUIRY_CANCEL:
2137 hci_cc_inquiry_cancel(hdev, skb);
2138 break;
2139
Andre Guedes4d934832012-03-21 00:03:35 -03002140 case HCI_OP_PERIODIC_INQ:
2141 hci_cc_periodic_inq(hdev, skb);
2142 break;
2143
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002144 case HCI_OP_EXIT_PERIODIC_INQ:
2145 hci_cc_exit_periodic_inq(hdev, skb);
2146 break;
2147
2148 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2149 hci_cc_remote_name_req_cancel(hdev, skb);
2150 break;
2151
2152 case HCI_OP_ROLE_DISCOVERY:
2153 hci_cc_role_discovery(hdev, skb);
2154 break;
2155
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002156 case HCI_OP_READ_LINK_POLICY:
2157 hci_cc_read_link_policy(hdev, skb);
2158 break;
2159
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002160 case HCI_OP_WRITE_LINK_POLICY:
2161 hci_cc_write_link_policy(hdev, skb);
2162 break;
2163
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002164 case HCI_OP_READ_DEF_LINK_POLICY:
2165 hci_cc_read_def_link_policy(hdev, skb);
2166 break;
2167
2168 case HCI_OP_WRITE_DEF_LINK_POLICY:
2169 hci_cc_write_def_link_policy(hdev, skb);
2170 break;
2171
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002172 case HCI_OP_RESET:
2173 hci_cc_reset(hdev, skb);
2174 break;
2175
2176 case HCI_OP_WRITE_LOCAL_NAME:
2177 hci_cc_write_local_name(hdev, skb);
2178 break;
2179
2180 case HCI_OP_READ_LOCAL_NAME:
2181 hci_cc_read_local_name(hdev, skb);
2182 break;
2183
2184 case HCI_OP_WRITE_AUTH_ENABLE:
2185 hci_cc_write_auth_enable(hdev, skb);
2186 break;
2187
2188 case HCI_OP_WRITE_ENCRYPT_MODE:
2189 hci_cc_write_encrypt_mode(hdev, skb);
2190 break;
2191
2192 case HCI_OP_WRITE_SCAN_ENABLE:
2193 hci_cc_write_scan_enable(hdev, skb);
2194 break;
2195
2196 case HCI_OP_READ_CLASS_OF_DEV:
2197 hci_cc_read_class_of_dev(hdev, skb);
2198 break;
2199
2200 case HCI_OP_WRITE_CLASS_OF_DEV:
2201 hci_cc_write_class_of_dev(hdev, skb);
2202 break;
2203
2204 case HCI_OP_READ_VOICE_SETTING:
2205 hci_cc_read_voice_setting(hdev, skb);
2206 break;
2207
2208 case HCI_OP_WRITE_VOICE_SETTING:
2209 hci_cc_write_voice_setting(hdev, skb);
2210 break;
2211
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002212 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2213 hci_cc_read_num_supported_iac(hdev, skb);
2214 break;
2215
Marcel Holtmann333140b2008-07-14 20:13:48 +02002216 case HCI_OP_WRITE_SSP_MODE:
2217 hci_cc_write_ssp_mode(hdev, skb);
2218 break;
2219
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08002220 case HCI_OP_WRITE_SC_SUPPORT:
2221 hci_cc_write_sc_support(hdev, skb);
2222 break;
2223
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002224 case HCI_OP_READ_LOCAL_VERSION:
2225 hci_cc_read_local_version(hdev, skb);
2226 break;
2227
2228 case HCI_OP_READ_LOCAL_COMMANDS:
2229 hci_cc_read_local_commands(hdev, skb);
2230 break;
2231
2232 case HCI_OP_READ_LOCAL_FEATURES:
2233 hci_cc_read_local_features(hdev, skb);
2234 break;
2235
Andre Guedes971e3a42011-06-30 19:20:52 -03002236 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2237 hci_cc_read_local_ext_features(hdev, skb);
2238 break;
2239
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002240 case HCI_OP_READ_BUFFER_SIZE:
2241 hci_cc_read_buffer_size(hdev, skb);
2242 break;
2243
2244 case HCI_OP_READ_BD_ADDR:
2245 hci_cc_read_bd_addr(hdev, skb);
2246 break;
2247
Johan Hedbergf332ec62013-03-15 17:07:11 -05002248 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2249 hci_cc_read_page_scan_activity(hdev, skb);
2250 break;
2251
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002252 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2253 hci_cc_write_page_scan_activity(hdev, skb);
2254 break;
2255
Johan Hedbergf332ec62013-03-15 17:07:11 -05002256 case HCI_OP_READ_PAGE_SCAN_TYPE:
2257 hci_cc_read_page_scan_type(hdev, skb);
2258 break;
2259
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002260 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2261 hci_cc_write_page_scan_type(hdev, skb);
2262 break;
2263
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002264 case HCI_OP_READ_DATA_BLOCK_SIZE:
2265 hci_cc_read_data_block_size(hdev, skb);
2266 break;
2267
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002268 case HCI_OP_READ_FLOW_CONTROL_MODE:
2269 hci_cc_read_flow_control_mode(hdev, skb);
2270 break;
2271
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002272 case HCI_OP_READ_LOCAL_AMP_INFO:
2273 hci_cc_read_local_amp_info(hdev, skb);
2274 break;
2275
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002276 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2277 hci_cc_read_local_amp_assoc(hdev, skb);
2278 break;
2279
Johan Hedbergd5859e22011-01-25 01:19:58 +02002280 case HCI_OP_READ_INQ_RSP_TX_POWER:
2281 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2282 break;
2283
Johan Hedberg980e1a52011-01-22 06:10:07 +02002284 case HCI_OP_PIN_CODE_REPLY:
2285 hci_cc_pin_code_reply(hdev, skb);
2286 break;
2287
2288 case HCI_OP_PIN_CODE_NEG_REPLY:
2289 hci_cc_pin_code_neg_reply(hdev, skb);
2290 break;
2291
Szymon Jancc35938b2011-03-22 13:12:21 +01002292 case HCI_OP_READ_LOCAL_OOB_DATA:
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08002293 hci_cc_read_local_oob_data(hdev, skb);
2294 break;
2295
2296 case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
2297 hci_cc_read_local_oob_ext_data(hdev, skb);
Szymon Jancc35938b2011-03-22 13:12:21 +01002298 break;
2299
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002300 case HCI_OP_LE_READ_BUFFER_SIZE:
2301 hci_cc_le_read_buffer_size(hdev, skb);
2302 break;
2303
Johan Hedberg60e77322013-01-22 14:01:59 +02002304 case HCI_OP_LE_READ_LOCAL_FEATURES:
2305 hci_cc_le_read_local_features(hdev, skb);
2306 break;
2307
Johan Hedberg8fa19092012-10-19 20:57:49 +03002308 case HCI_OP_LE_READ_ADV_TX_POWER:
2309 hci_cc_le_read_adv_tx_power(hdev, skb);
2310 break;
2311
Johan Hedberga5c29682011-02-19 12:05:57 -03002312 case HCI_OP_USER_CONFIRM_REPLY:
2313 hci_cc_user_confirm_reply(hdev, skb);
2314 break;
2315
2316 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2317 hci_cc_user_confirm_neg_reply(hdev, skb);
2318 break;
2319
Brian Gix1143d452011-11-23 08:28:34 -08002320 case HCI_OP_USER_PASSKEY_REPLY:
2321 hci_cc_user_passkey_reply(hdev, skb);
2322 break;
2323
2324 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2325 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002326 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002327
Marcel Holtmann7a4cd512014-02-19 19:52:13 -08002328 case HCI_OP_LE_SET_RANDOM_ADDR:
2329 hci_cc_le_set_random_addr(hdev, skb);
2330 break;
2331
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002332 case HCI_OP_LE_SET_ADV_ENABLE:
2333 hci_cc_le_set_adv_enable(hdev, skb);
2334 break;
2335
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002336 case HCI_OP_LE_SET_SCAN_ENABLE:
2337 hci_cc_le_set_scan_enable(hdev, skb);
2338 break;
2339
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002340 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2341 hci_cc_le_read_white_list_size(hdev, skb);
2342 break;
2343
Johan Hedberg9b008c02013-01-22 14:02:01 +02002344 case HCI_OP_LE_READ_SUPPORTED_STATES:
2345 hci_cc_le_read_supported_states(hdev, skb);
2346 break;
2347
Andre Guedesf9b49302011-06-30 19:20:53 -03002348 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2349 hci_cc_write_le_host_supported(hdev, skb);
2350 break;
2351
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002352 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2353 hci_cc_write_remote_amp_assoc(hdev, skb);
2354 break;
2355
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002356 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002357 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002358 break;
2359 }
2360
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002361 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002362 del_timer(&hdev->cmd_timer);
2363
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002364 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002365
Szymon Jancdbccd792012-12-11 08:51:19 +01002366 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002367 atomic_set(&hdev->cmd_cnt, 1);
2368 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002369 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002370 }
2371}
2372
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002373static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002374{
2375 struct hci_ev_cmd_status *ev = (void *) skb->data;
2376 __u16 opcode;
2377
2378 skb_pull(skb, sizeof(*ev));
2379
2380 opcode = __le16_to_cpu(ev->opcode);
2381
2382 switch (opcode) {
2383 case HCI_OP_INQUIRY:
2384 hci_cs_inquiry(hdev, ev->status);
2385 break;
2386
2387 case HCI_OP_CREATE_CONN:
2388 hci_cs_create_conn(hdev, ev->status);
2389 break;
2390
2391 case HCI_OP_ADD_SCO:
2392 hci_cs_add_sco(hdev, ev->status);
2393 break;
2394
Marcel Holtmannf8558552008-07-14 20:13:49 +02002395 case HCI_OP_AUTH_REQUESTED:
2396 hci_cs_auth_requested(hdev, ev->status);
2397 break;
2398
2399 case HCI_OP_SET_CONN_ENCRYPT:
2400 hci_cs_set_conn_encrypt(hdev, ev->status);
2401 break;
2402
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002403 case HCI_OP_REMOTE_NAME_REQ:
2404 hci_cs_remote_name_req(hdev, ev->status);
2405 break;
2406
Marcel Holtmann769be972008-07-14 20:13:49 +02002407 case HCI_OP_READ_REMOTE_FEATURES:
2408 hci_cs_read_remote_features(hdev, ev->status);
2409 break;
2410
2411 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2412 hci_cs_read_remote_ext_features(hdev, ev->status);
2413 break;
2414
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002415 case HCI_OP_SETUP_SYNC_CONN:
2416 hci_cs_setup_sync_conn(hdev, ev->status);
2417 break;
2418
2419 case HCI_OP_SNIFF_MODE:
2420 hci_cs_sniff_mode(hdev, ev->status);
2421 break;
2422
2423 case HCI_OP_EXIT_SNIFF_MODE:
2424 hci_cs_exit_sniff_mode(hdev, ev->status);
2425 break;
2426
Johan Hedberg8962ee72011-01-20 12:40:27 +02002427 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002428 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002429 break;
2430
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002431 case HCI_OP_CREATE_PHY_LINK:
2432 hci_cs_create_phylink(hdev, ev->status);
2433 break;
2434
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002435 case HCI_OP_ACCEPT_PHY_LINK:
2436 hci_cs_accept_phylink(hdev, ev->status);
2437 break;
2438
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002439 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002440 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002441 break;
2442 }
2443
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002444 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002445 del_timer(&hdev->cmd_timer);
2446
Johan Hedberg02350a72013-04-03 21:50:29 +03002447 if (ev->status ||
2448 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2449 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002450
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002451 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002452 atomic_set(&hdev->cmd_cnt, 1);
2453 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002454 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002455 }
2456}
2457
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002458static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002459{
2460 struct hci_ev_role_change *ev = (void *) skb->data;
2461 struct hci_conn *conn;
2462
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002463 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002464
2465 hci_dev_lock(hdev);
2466
2467 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2468 if (conn) {
2469 if (!ev->status) {
2470 if (ev->role)
2471 conn->link_mode &= ~HCI_LM_MASTER;
2472 else
2473 conn->link_mode |= HCI_LM_MASTER;
2474 }
2475
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002476 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002477
2478 hci_role_switch_cfm(conn, ev->status, ev->role);
2479 }
2480
2481 hci_dev_unlock(hdev);
2482}
2483
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002484static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002486 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487 int i;
2488
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002489 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2490 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2491 return;
2492 }
2493
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002494 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002495 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496 BT_DBG("%s bad parameters", hdev->name);
2497 return;
2498 }
2499
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002500 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2501
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002502 for (i = 0; i < ev->num_hndl; i++) {
2503 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504 struct hci_conn *conn;
2505 __u16 handle, count;
2506
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002507 handle = __le16_to_cpu(info->handle);
2508 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002509
2510 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002511 if (!conn)
2512 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002513
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002514 conn->sent -= count;
2515
2516 switch (conn->type) {
2517 case ACL_LINK:
2518 hdev->acl_cnt += count;
2519 if (hdev->acl_cnt > hdev->acl_pkts)
2520 hdev->acl_cnt = hdev->acl_pkts;
2521 break;
2522
2523 case LE_LINK:
2524 if (hdev->le_pkts) {
2525 hdev->le_cnt += count;
2526 if (hdev->le_cnt > hdev->le_pkts)
2527 hdev->le_cnt = hdev->le_pkts;
2528 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002529 hdev->acl_cnt += count;
2530 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002531 hdev->acl_cnt = hdev->acl_pkts;
2532 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002533 break;
2534
2535 case SCO_LINK:
2536 hdev->sco_cnt += count;
2537 if (hdev->sco_cnt > hdev->sco_pkts)
2538 hdev->sco_cnt = hdev->sco_pkts;
2539 break;
2540
2541 default:
2542 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2543 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544 }
2545 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002546
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002547 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548}
2549
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002550static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2551 __u16 handle)
2552{
2553 struct hci_chan *chan;
2554
2555 switch (hdev->dev_type) {
2556 case HCI_BREDR:
2557 return hci_conn_hash_lookup_handle(hdev, handle);
2558 case HCI_AMP:
2559 chan = hci_chan_lookup_handle(hdev, handle);
2560 if (chan)
2561 return chan->conn;
2562 break;
2563 default:
2564 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2565 break;
2566 }
2567
2568 return NULL;
2569}
2570
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002571static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002572{
2573 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2574 int i;
2575
2576 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2577 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2578 return;
2579 }
2580
2581 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002582 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002583 BT_DBG("%s bad parameters", hdev->name);
2584 return;
2585 }
2586
2587 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002588 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002589
2590 for (i = 0; i < ev->num_hndl; i++) {
2591 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002592 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002593 __u16 handle, block_count;
2594
2595 handle = __le16_to_cpu(info->handle);
2596 block_count = __le16_to_cpu(info->blocks);
2597
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002598 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002599 if (!conn)
2600 continue;
2601
2602 conn->sent -= block_count;
2603
2604 switch (conn->type) {
2605 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002606 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002607 hdev->block_cnt += block_count;
2608 if (hdev->block_cnt > hdev->num_blocks)
2609 hdev->block_cnt = hdev->num_blocks;
2610 break;
2611
2612 default:
2613 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2614 break;
2615 }
2616 }
2617
2618 queue_work(hdev->workqueue, &hdev->tx_work);
2619}
2620
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002621static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002622{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002623 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002624 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002625
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002626 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627
2628 hci_dev_lock(hdev);
2629
Marcel Holtmann04837f62006-07-03 10:02:33 +02002630 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2631 if (conn) {
2632 conn->mode = ev->mode;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002633
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002634 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2635 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002636 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002637 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002638 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002639 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002640 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002641
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002642 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002643 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002644 }
2645
2646 hci_dev_unlock(hdev);
2647}
2648
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002649static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002651 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2652 struct hci_conn *conn;
2653
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002654 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002655
2656 hci_dev_lock(hdev);
2657
2658 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002659 if (!conn)
2660 goto unlock;
2661
2662 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002663 hci_conn_hold(conn);
2664 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002665 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002666 }
2667
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002668 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002669 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002670 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002671 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002672 u8 secure;
2673
2674 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2675 secure = 1;
2676 else
2677 secure = 0;
2678
Johan Hedberg744cf192011-11-08 20:40:14 +02002679 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002680 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002681
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002682unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002683 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002684}
2685
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002686static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002687{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002688 struct hci_ev_link_key_req *ev = (void *) skb->data;
2689 struct hci_cp_link_key_reply cp;
2690 struct hci_conn *conn;
2691 struct link_key *key;
2692
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002693 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002694
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002695 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002696 return;
2697
2698 hci_dev_lock(hdev);
2699
2700 key = hci_find_link_key(hdev, &ev->bdaddr);
2701 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002702 BT_DBG("%s link key not found for %pMR", hdev->name,
2703 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002704 goto not_found;
2705 }
2706
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002707 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2708 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002709
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002710 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002711 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002712 BT_DBG("%s ignoring debug key", hdev->name);
2713 goto not_found;
2714 }
2715
2716 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002717 if (conn) {
Marcel Holtmann66138ce2014-01-10 02:07:20 -08002718 if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
2719 key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002720 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002721 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2722 goto not_found;
2723 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002724
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002725 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002726 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002727 BT_DBG("%s ignoring key unauthenticated for high security",
2728 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002729 goto not_found;
2730 }
2731
2732 conn->key_type = key->type;
2733 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002734 }
2735
2736 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002737 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002738
2739 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2740
2741 hci_dev_unlock(hdev);
2742
2743 return;
2744
2745not_found:
2746 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2747 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002748}
2749
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002750static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002752 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2753 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002754 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002755
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002756 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002757
2758 hci_dev_lock(hdev);
2759
2760 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2761 if (conn) {
2762 hci_conn_hold(conn);
2763 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002764 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002765
2766 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2767 conn->key_type = ev->key_type;
2768
David Herrmann76a68ba2013-04-06 20:28:37 +02002769 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002770 }
2771
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002772 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002773 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002774 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002775
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002776 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002777}
2778
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002779static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002780{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002781 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002782 struct hci_conn *conn;
2783
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002784 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002785
2786 hci_dev_lock(hdev);
2787
2788 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002789 if (conn && !ev->status) {
2790 struct inquiry_entry *ie;
2791
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002792 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2793 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002794 ie->data.clock_offset = ev->clock_offset;
2795 ie->timestamp = jiffies;
2796 }
2797 }
2798
2799 hci_dev_unlock(hdev);
2800}
2801
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002802static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002803{
2804 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2805 struct hci_conn *conn;
2806
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002807 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002808
2809 hci_dev_lock(hdev);
2810
2811 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2812 if (conn && !ev->status)
2813 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2814
2815 hci_dev_unlock(hdev);
2816}
2817
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002818static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002819{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002820 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002821 struct inquiry_entry *ie;
2822
2823 BT_DBG("%s", hdev->name);
2824
2825 hci_dev_lock(hdev);
2826
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002827 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2828 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002829 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2830 ie->timestamp = jiffies;
2831 }
2832
2833 hci_dev_unlock(hdev);
2834}
2835
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002836static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2837 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002838{
2839 struct inquiry_data data;
2840 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002841 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002842
2843 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2844
2845 if (!num_rsp)
2846 return;
2847
Andre Guedes1519cc12012-03-21 00:03:38 -03002848 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2849 return;
2850
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002851 hci_dev_lock(hdev);
2852
2853 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002854 struct inquiry_info_with_rssi_and_pscan_mode *info;
2855 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002856
Johan Hedberge17acd42011-03-30 23:57:16 +03002857 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002858 bacpy(&data.bdaddr, &info->bdaddr);
2859 data.pscan_rep_mode = info->pscan_rep_mode;
2860 data.pscan_period_mode = info->pscan_period_mode;
2861 data.pscan_mode = info->pscan_mode;
2862 memcpy(data.dev_class, info->dev_class, 3);
2863 data.clock_offset = info->clock_offset;
2864 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002865 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002866
2867 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002868 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002869 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002870 info->dev_class, info->rssi,
2871 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002872 }
2873 } else {
2874 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2875
Johan Hedberge17acd42011-03-30 23:57:16 +03002876 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002877 bacpy(&data.bdaddr, &info->bdaddr);
2878 data.pscan_rep_mode = info->pscan_rep_mode;
2879 data.pscan_period_mode = info->pscan_period_mode;
2880 data.pscan_mode = 0x00;
2881 memcpy(data.dev_class, info->dev_class, 3);
2882 data.clock_offset = info->clock_offset;
2883 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002884 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002885 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002886 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002887 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002888 info->dev_class, info->rssi,
2889 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002890 }
2891 }
2892
2893 hci_dev_unlock(hdev);
2894}
2895
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002896static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2897 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002898{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002899 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2900 struct hci_conn *conn;
2901
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002902 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002903
Marcel Holtmann41a96212008-07-14 20:13:48 +02002904 hci_dev_lock(hdev);
2905
2906 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002907 if (!conn)
2908 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002909
Johan Hedbergcad718e2013-04-17 15:00:51 +03002910 if (ev->page < HCI_MAX_PAGES)
2911 memcpy(conn->features[ev->page], ev->features, 8);
2912
Johan Hedbergccd556f2010-11-10 17:11:51 +02002913 if (!ev->status && ev->page == 0x01) {
2914 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002915
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002916 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2917 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002918 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002919
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302920 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002921 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302922 } else {
2923 /* It is mandatory by the Bluetooth specification that
2924 * Extended Inquiry Results are only used when Secure
2925 * Simple Pairing is enabled, but some devices violate
2926 * this.
2927 *
2928 * To make these devices work, the internal SSP
2929 * enabled flag needs to be cleared if the remote host
2930 * features do not indicate SSP support */
2931 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2932 }
Marcel Holtmanneb9a8f32014-01-15 22:37:38 -08002933
2934 if (ev->features[0] & LMP_HOST_SC)
2935 set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002936 }
2937
Johan Hedbergccd556f2010-11-10 17:11:51 +02002938 if (conn->state != BT_CONFIG)
2939 goto unlock;
2940
Johan Hedberg671267b2012-05-12 16:11:50 -03002941 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002942 struct hci_cp_remote_name_req cp;
2943 memset(&cp, 0, sizeof(cp));
2944 bacpy(&cp.bdaddr, &conn->dst);
2945 cp.pscan_rep_mode = 0x02;
2946 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002947 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2948 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002949 conn->dst_type, 0, NULL, 0,
2950 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002951
Johan Hedberg127178d2010-11-18 22:22:29 +02002952 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002953 conn->state = BT_CONNECTED;
2954 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002955 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002956 }
2957
2958unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002959 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002960}
2961
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002962static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2963 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002964{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002965 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2966 struct hci_conn *conn;
2967
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002968 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002969
2970 hci_dev_lock(hdev);
2971
2972 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002973 if (!conn) {
2974 if (ev->link_type == ESCO_LINK)
2975 goto unlock;
2976
2977 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2978 if (!conn)
2979 goto unlock;
2980
2981 conn->type = SCO_LINK;
2982 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002983
Marcel Holtmann732547f2009-04-19 19:14:14 +02002984 switch (ev->status) {
2985 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002986 conn->handle = __le16_to_cpu(ev->handle);
2987 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002988
2989 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002990 break;
2991
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02002992 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05002993 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002994 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002995 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002996 case 0x1f: /* Unspecified error */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002997 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02002998 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2999 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003000 if (hci_setup_sync(conn, conn->link->handle))
3001 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003002 }
3003 /* fall through */
3004
3005 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003006 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003007 break;
3008 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003009
3010 hci_proto_connect_cfm(conn, ev->status);
3011 if (ev->status)
3012 hci_conn_del(conn);
3013
3014unlock:
3015 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003016}
3017
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07003018static inline size_t eir_get_length(u8 *eir, size_t eir_len)
3019{
3020 size_t parsed = 0;
3021
3022 while (parsed < eir_len) {
3023 u8 field_len = eir[0];
3024
3025 if (field_len == 0)
3026 return parsed;
3027
3028 parsed += field_len + 1;
3029 eir += field_len + 1;
3030 }
3031
3032 return eir_len;
3033}
3034
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003035static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3036 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003037{
3038 struct inquiry_data data;
3039 struct extended_inquiry_info *info = (void *) (skb->data + 1);
3040 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303041 size_t eir_len;
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
Johan Hedberge17acd42011-03-30 23:57:16 +03003053 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003054 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003055
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003056 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003057 data.pscan_rep_mode = info->pscan_rep_mode;
3058 data.pscan_period_mode = info->pscan_period_mode;
3059 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003060 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003061 data.clock_offset = info->clock_offset;
3062 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003063 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003064
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003065 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003066 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003067 sizeof(info->data),
3068 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003069 else
3070 name_known = true;
3071
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003072 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003073 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303074 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003075 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003076 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303077 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003078 }
3079
3080 hci_dev_unlock(hdev);
3081}
3082
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003083static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3084 struct sk_buff *skb)
3085{
3086 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3087 struct hci_conn *conn;
3088
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003089 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003090 __le16_to_cpu(ev->handle));
3091
3092 hci_dev_lock(hdev);
3093
3094 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3095 if (!conn)
3096 goto unlock;
3097
3098 if (!ev->status)
3099 conn->sec_level = conn->pending_sec_level;
3100
3101 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3102
3103 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003104 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003105 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003106 goto unlock;
3107 }
3108
3109 if (conn->state == BT_CONFIG) {
3110 if (!ev->status)
3111 conn->state = BT_CONNECTED;
3112
3113 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003114 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003115 } else {
3116 hci_auth_cfm(conn, ev->status);
3117
3118 hci_conn_hold(conn);
3119 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003120 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003121 }
3122
3123unlock:
3124 hci_dev_unlock(hdev);
3125}
3126
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003127static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003128{
3129 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003130 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3131 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003132 /* If both remote and local IO capabilities allow MITM
3133 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003134 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3135 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3136 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003137 else
Mikel Astizacabae92013-06-28 10:56:28 +02003138 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003139 }
3140
3141 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003142 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3143 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003144 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003145
3146 return conn->auth_type;
3147}
3148
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003149static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003150{
3151 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3152 struct hci_conn *conn;
3153
3154 BT_DBG("%s", hdev->name);
3155
3156 hci_dev_lock(hdev);
3157
3158 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003159 if (!conn)
3160 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003161
Johan Hedberg03b555e2011-01-04 15:40:05 +02003162 hci_conn_hold(conn);
3163
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003164 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003165 goto unlock;
3166
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003167 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003168 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003169 struct hci_cp_io_capability_reply cp;
3170
3171 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303172 /* Change the IO capability from KeyboardDisplay
3173 * to DisplayYesNo as it is not supported by BT spec. */
3174 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003175 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003176 conn->auth_type = hci_get_auth_req(conn);
3177 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003178
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003179 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3180 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003181 cp.oob_data = 0x01;
3182 else
3183 cp.oob_data = 0x00;
3184
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003185 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003186 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003187 } else {
3188 struct hci_cp_io_capability_neg_reply cp;
3189
3190 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003191 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003192
3193 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003194 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003195 }
3196
3197unlock:
3198 hci_dev_unlock(hdev);
3199}
3200
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003201static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003202{
3203 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3204 struct hci_conn *conn;
3205
3206 BT_DBG("%s", hdev->name);
3207
3208 hci_dev_lock(hdev);
3209
3210 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3211 if (!conn)
3212 goto unlock;
3213
Johan Hedberg03b555e2011-01-04 15:40:05 +02003214 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003215 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003216 if (ev->oob_data)
3217 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003218
3219unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003220 hci_dev_unlock(hdev);
3221}
3222
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003223static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3224 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003225{
3226 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003227 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003228 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003229
3230 BT_DBG("%s", hdev->name);
3231
3232 hci_dev_lock(hdev);
3233
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003234 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003235 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003236
Johan Hedberg7a828902011-04-28 11:28:53 -07003237 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3238 if (!conn)
3239 goto unlock;
3240
3241 loc_mitm = (conn->auth_type & 0x01);
3242 rem_mitm = (conn->remote_auth & 0x01);
3243
3244 /* If we require MITM but the remote device can't provide that
3245 * (it has NoInputNoOutput) then reject the confirmation
3246 * request. The only exception is when we're dedicated bonding
3247 * initiators (connect_cfm_cb set) since then we always have the MITM
3248 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003249 if (!conn->connect_cfm_cb && loc_mitm &&
3250 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003251 BT_DBG("Rejecting request: remote device can't provide MITM");
3252 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003253 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003254 goto unlock;
3255 }
3256
3257 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003258 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3259 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003260
3261 /* If we're not the initiators request authorization to
3262 * proceed from user space (mgmt_user_confirm with
3263 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003264 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003265 BT_DBG("Confirming auto-accept as acceptor");
3266 confirm_hint = 1;
3267 goto confirm;
3268 }
3269
Johan Hedberg9f616562011-04-28 11:28:54 -07003270 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003271 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003272
3273 if (hdev->auto_accept_delay > 0) {
3274 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
Johan Hedberg7bc18d92013-10-16 18:11:39 +03003275 queue_delayed_work(conn->hdev->workqueue,
3276 &conn->auto_accept_work, delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003277 goto unlock;
3278 }
3279
Johan Hedberg7a828902011-04-28 11:28:53 -07003280 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003281 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003282 goto unlock;
3283 }
3284
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003285confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003286 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003287 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003288
3289unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003290 hci_dev_unlock(hdev);
3291}
3292
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003293static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3294 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003295{
3296 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3297
3298 BT_DBG("%s", hdev->name);
3299
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003300 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003301 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003302}
3303
Johan Hedberg92a25252012-09-06 18:39:26 +03003304static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3305 struct sk_buff *skb)
3306{
3307 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3308 struct hci_conn *conn;
3309
3310 BT_DBG("%s", hdev->name);
3311
3312 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3313 if (!conn)
3314 return;
3315
3316 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3317 conn->passkey_entered = 0;
3318
3319 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3320 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3321 conn->dst_type, conn->passkey_notify,
3322 conn->passkey_entered);
3323}
3324
3325static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3326{
3327 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3328 struct hci_conn *conn;
3329
3330 BT_DBG("%s", hdev->name);
3331
3332 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3333 if (!conn)
3334 return;
3335
3336 switch (ev->type) {
3337 case HCI_KEYPRESS_STARTED:
3338 conn->passkey_entered = 0;
3339 return;
3340
3341 case HCI_KEYPRESS_ENTERED:
3342 conn->passkey_entered++;
3343 break;
3344
3345 case HCI_KEYPRESS_ERASED:
3346 conn->passkey_entered--;
3347 break;
3348
3349 case HCI_KEYPRESS_CLEARED:
3350 conn->passkey_entered = 0;
3351 break;
3352
3353 case HCI_KEYPRESS_COMPLETED:
3354 return;
3355 }
3356
3357 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3358 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3359 conn->dst_type, conn->passkey_notify,
3360 conn->passkey_entered);
3361}
3362
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003363static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3364 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003365{
3366 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3367 struct hci_conn *conn;
3368
3369 BT_DBG("%s", hdev->name);
3370
3371 hci_dev_lock(hdev);
3372
3373 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003374 if (!conn)
3375 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003376
Johan Hedberg2a611692011-02-19 12:06:00 -03003377 /* To avoid duplicate auth_failed events to user space we check
3378 * the HCI_CONN_AUTH_PEND flag which will be set if we
3379 * initiated the authentication. A traditional auth_complete
3380 * event gets always produced as initiator and is also mapped to
3381 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003382 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003383 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003384 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003385
David Herrmann76a68ba2013-04-06 20:28:37 +02003386 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003387
3388unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003389 hci_dev_unlock(hdev);
3390}
3391
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003392static void hci_remote_host_features_evt(struct hci_dev *hdev,
3393 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003394{
3395 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3396 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003397 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003398
3399 BT_DBG("%s", hdev->name);
3400
3401 hci_dev_lock(hdev);
3402
Johan Hedbergcad718e2013-04-17 15:00:51 +03003403 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3404 if (conn)
3405 memcpy(conn->features[1], ev->features, 8);
3406
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003407 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3408 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003409 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003410
3411 hci_dev_unlock(hdev);
3412}
3413
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003414static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3415 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003416{
3417 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3418 struct oob_data *data;
3419
3420 BT_DBG("%s", hdev->name);
3421
3422 hci_dev_lock(hdev);
3423
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003424 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003425 goto unlock;
3426
Szymon Janc2763eda2011-03-22 13:12:22 +01003427 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3428 if (data) {
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003429 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
3430 struct hci_cp_remote_oob_ext_data_reply cp;
Szymon Janc2763eda2011-03-22 13:12:22 +01003431
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003432 bacpy(&cp.bdaddr, &ev->bdaddr);
3433 memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
3434 memcpy(cp.randomizer192, data->randomizer192,
3435 sizeof(cp.randomizer192));
3436 memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
3437 memcpy(cp.randomizer256, data->randomizer256,
3438 sizeof(cp.randomizer256));
Szymon Janc2763eda2011-03-22 13:12:22 +01003439
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003440 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
3441 sizeof(cp), &cp);
3442 } else {
3443 struct hci_cp_remote_oob_data_reply cp;
3444
3445 bacpy(&cp.bdaddr, &ev->bdaddr);
3446 memcpy(cp.hash, data->hash192, sizeof(cp.hash));
3447 memcpy(cp.randomizer, data->randomizer192,
3448 sizeof(cp.randomizer));
3449
3450 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
3451 sizeof(cp), &cp);
3452 }
Szymon Janc2763eda2011-03-22 13:12:22 +01003453 } else {
3454 struct hci_cp_remote_oob_data_neg_reply cp;
3455
3456 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003457 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
3458 sizeof(cp), &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003459 }
3460
Szymon Jance1ba1f12011-04-06 13:01:59 +02003461unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003462 hci_dev_unlock(hdev);
3463}
3464
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003465static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3466 struct sk_buff *skb)
3467{
3468 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3469 struct hci_conn *hcon, *bredr_hcon;
3470
3471 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3472 ev->status);
3473
3474 hci_dev_lock(hdev);
3475
3476 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3477 if (!hcon) {
3478 hci_dev_unlock(hdev);
3479 return;
3480 }
3481
3482 if (ev->status) {
3483 hci_conn_del(hcon);
3484 hci_dev_unlock(hdev);
3485 return;
3486 }
3487
3488 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3489
3490 hcon->state = BT_CONNECTED;
3491 bacpy(&hcon->dst, &bredr_hcon->dst);
3492
3493 hci_conn_hold(hcon);
3494 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003495 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003496
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003497 hci_conn_add_sysfs(hcon);
3498
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003499 amp_physical_cfm(bredr_hcon, hcon);
3500
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003501 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003502}
3503
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003504static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3505{
3506 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3507 struct hci_conn *hcon;
3508 struct hci_chan *hchan;
3509 struct amp_mgr *mgr;
3510
3511 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3512 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3513 ev->status);
3514
3515 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3516 if (!hcon)
3517 return;
3518
3519 /* Create AMP hchan */
3520 hchan = hci_chan_create(hcon);
3521 if (!hchan)
3522 return;
3523
3524 hchan->handle = le16_to_cpu(ev->handle);
3525
3526 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3527
3528 mgr = hcon->amp_mgr;
3529 if (mgr && mgr->bredr_chan) {
3530 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3531
3532 l2cap_chan_lock(bredr_chan);
3533
3534 bredr_chan->conn->mtu = hdev->block_mtu;
3535 l2cap_logical_cfm(bredr_chan, hchan, 0);
3536 hci_conn_hold(hcon);
3537
3538 l2cap_chan_unlock(bredr_chan);
3539 }
3540}
3541
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003542static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3543 struct sk_buff *skb)
3544{
3545 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3546 struct hci_chan *hchan;
3547
3548 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3549 le16_to_cpu(ev->handle), ev->status);
3550
3551 if (ev->status)
3552 return;
3553
3554 hci_dev_lock(hdev);
3555
3556 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3557 if (!hchan)
3558 goto unlock;
3559
3560 amp_destroy_logical_link(hchan, ev->reason);
3561
3562unlock:
3563 hci_dev_unlock(hdev);
3564}
3565
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003566static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3567 struct sk_buff *skb)
3568{
3569 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3570 struct hci_conn *hcon;
3571
3572 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3573
3574 if (ev->status)
3575 return;
3576
3577 hci_dev_lock(hdev);
3578
3579 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3580 if (hcon) {
3581 hcon->state = BT_CLOSED;
3582 hci_conn_del(hcon);
3583 }
3584
3585 hci_dev_unlock(hdev);
3586}
3587
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003588static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003589{
3590 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3591 struct hci_conn *conn;
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003592 struct smp_irk *irk;
Ville Tervofcd89c02011-02-10 22:38:47 -03003593
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003594 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003595
3596 hci_dev_lock(hdev);
3597
Andre Guedesb47a09b2012-07-27 15:10:15 -03003598 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003599 if (!conn) {
3600 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3601 if (!conn) {
3602 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003603 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003604 }
Andre Guedes29b79882011-05-31 14:20:54 -03003605
3606 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003607
Marcel Holtmann880be4e2013-10-13 07:25:18 -07003608 /* The advertising parameters for own address type
3609 * define which source address and source address
3610 * type this connections has.
3611 */
3612 if (bacmp(&conn->src, BDADDR_ANY)) {
3613 conn->src_type = ADDR_LE_DEV_PUBLIC;
3614 } else {
3615 bacpy(&conn->src, &hdev->static_addr);
3616 conn->src_type = ADDR_LE_DEV_RANDOM;
3617 }
3618
Andre Guedesb9b343d2012-07-27 15:10:11 -03003619 if (ev->role == LE_CONN_ROLE_MASTER) {
3620 conn->out = true;
3621 conn->link_mode |= HCI_LM_MASTER;
3622 }
Ville Tervob62f3282011-02-10 22:38:50 -03003623 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003624
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003625 /* Ensure that the hci_conn contains the identity address type
3626 * regardless of which address the connection was made with.
3627 *
3628 * If the controller has a public BD_ADDR, then by default
3629 * use that one. If this is a LE only controller without
3630 * a public address, default to the static random address.
3631 *
3632 * For debugging purposes it is possible to force
3633 * controllers with a public address to use the static
3634 * random address instead.
3635 */
3636 if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ||
3637 !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
3638 bacpy(&conn->src, &hdev->static_addr);
3639 conn->src_type = ADDR_LE_DEV_RANDOM;
3640 } else {
3641 bacpy(&conn->src, &hdev->bdaddr);
3642 conn->src_type = ADDR_LE_DEV_PUBLIC;
3643 }
3644
Marcel Holtmannedb4b462014-02-18 15:13:43 -08003645 /* Lookup the identity address from the stored connection
3646 * address and address type.
3647 *
3648 * When establishing connections to an identity address, the
3649 * connection procedure will store the resolvable random
3650 * address first. Now if it can be converted back into the
3651 * identity address, start using the identity address from
3652 * now on.
3653 */
3654 irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003655 if (irk) {
3656 bacpy(&conn->dst, &irk->bdaddr);
3657 conn->dst_type = irk->addr_type;
3658 }
3659
Andre Guedescd17dec2012-07-27 15:10:16 -03003660 if (ev->status) {
3661 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3662 conn->dst_type, ev->status);
3663 hci_proto_connect_cfm(conn, ev->status);
3664 conn->state = BT_CLOSED;
3665 hci_conn_del(conn);
3666 goto unlock;
3667 }
3668
Johan Hedbergb644ba32012-01-17 21:48:47 +02003669 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Marcel Holtmann01fdb0f2014-02-18 14:22:19 -08003670 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003671 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003672
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003673 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003674 conn->handle = __le16_to_cpu(ev->handle);
3675 conn->state = BT_CONNECTED;
3676
Jukka Rissanen18722c22013-12-11 17:05:37 +02003677 if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
3678 set_bit(HCI_CONN_6LOWPAN, &conn->flags);
3679
Ville Tervofcd89c02011-02-10 22:38:47 -03003680 hci_conn_add_sysfs(conn);
3681
3682 hci_proto_connect_cfm(conn, ev->status);
3683
3684unlock:
3685 hci_dev_unlock(hdev);
3686}
3687
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003688static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003689{
Andre Guedese95beb42011-09-26 20:48:35 -03003690 u8 num_reports = skb->data[0];
3691 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003692 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003693
Andre Guedese95beb42011-09-26 20:48:35 -03003694 while (num_reports--) {
3695 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003696
Andre Guedes3c9e9192012-01-10 18:20:50 -03003697 rssi = ev->data[ev->length];
3698 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003699 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003700
Andre Guedese95beb42011-09-26 20:48:35 -03003701 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003702 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003703}
3704
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003705static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003706{
3707 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3708 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003709 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003710 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003711 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003712
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003713 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003714
3715 hci_dev_lock(hdev);
3716
3717 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003718 if (conn == NULL)
3719 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003720
Johan Hedberg98a0b842014-01-30 19:40:00 -08003721 ltk = hci_find_ltk(hdev, ev->ediv, ev->random, conn->out);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003722 if (ltk == NULL)
3723 goto not_found;
3724
3725 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003726 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003727
3728 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03003729 conn->pending_sec_level = BT_SECURITY_HIGH;
3730 else
3731 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003732
Andre Guedes89cbb4d2013-07-31 16:25:29 -03003733 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003734
3735 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3736
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003737 if (ltk->type & HCI_SMP_STK) {
3738 list_del(&ltk->list);
3739 kfree(ltk);
3740 }
3741
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003742 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003743
3744 return;
3745
3746not_found:
3747 neg.handle = ev->handle;
3748 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3749 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003750}
3751
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003752static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003753{
3754 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3755
3756 skb_pull(skb, sizeof(*le_ev));
3757
3758 switch (le_ev->subevent) {
3759 case HCI_EV_LE_CONN_COMPLETE:
3760 hci_le_conn_complete_evt(hdev, skb);
3761 break;
3762
Andre Guedes9aa04c92011-05-26 16:23:51 -03003763 case HCI_EV_LE_ADVERTISING_REPORT:
3764 hci_le_adv_report_evt(hdev, skb);
3765 break;
3766
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003767 case HCI_EV_LE_LTK_REQ:
3768 hci_le_ltk_request_evt(hdev, skb);
3769 break;
3770
Ville Tervofcd89c02011-02-10 22:38:47 -03003771 default:
3772 break;
3773 }
3774}
3775
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003776static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3777{
3778 struct hci_ev_channel_selected *ev = (void *) skb->data;
3779 struct hci_conn *hcon;
3780
3781 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3782
3783 skb_pull(skb, sizeof(*ev));
3784
3785 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3786 if (!hcon)
3787 return;
3788
3789 amp_read_loc_assoc_final_data(hdev, hcon);
3790}
3791
Linus Torvalds1da177e2005-04-16 15:20:36 -07003792void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3793{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003794 struct hci_event_hdr *hdr = (void *) skb->data;
3795 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003796
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003797 hci_dev_lock(hdev);
3798
3799 /* Received events are (currently) only needed when a request is
3800 * ongoing so avoid unnecessary memory allocation.
3801 */
3802 if (hdev->req_status == HCI_REQ_PEND) {
3803 kfree_skb(hdev->recv_evt);
3804 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3805 }
3806
3807 hci_dev_unlock(hdev);
3808
Linus Torvalds1da177e2005-04-16 15:20:36 -07003809 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3810
Johan Hedberg02350a72013-04-03 21:50:29 +03003811 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02003812 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
3813 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03003814
3815 hci_req_cmd_complete(hdev, opcode, 0);
3816 }
3817
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003818 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003819 case HCI_EV_INQUIRY_COMPLETE:
3820 hci_inquiry_complete_evt(hdev, skb);
3821 break;
3822
3823 case HCI_EV_INQUIRY_RESULT:
3824 hci_inquiry_result_evt(hdev, skb);
3825 break;
3826
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003827 case HCI_EV_CONN_COMPLETE:
3828 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003829 break;
3830
Linus Torvalds1da177e2005-04-16 15:20:36 -07003831 case HCI_EV_CONN_REQUEST:
3832 hci_conn_request_evt(hdev, skb);
3833 break;
3834
Linus Torvalds1da177e2005-04-16 15:20:36 -07003835 case HCI_EV_DISCONN_COMPLETE:
3836 hci_disconn_complete_evt(hdev, skb);
3837 break;
3838
Linus Torvalds1da177e2005-04-16 15:20:36 -07003839 case HCI_EV_AUTH_COMPLETE:
3840 hci_auth_complete_evt(hdev, skb);
3841 break;
3842
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003843 case HCI_EV_REMOTE_NAME:
3844 hci_remote_name_evt(hdev, skb);
3845 break;
3846
Linus Torvalds1da177e2005-04-16 15:20:36 -07003847 case HCI_EV_ENCRYPT_CHANGE:
3848 hci_encrypt_change_evt(hdev, skb);
3849 break;
3850
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003851 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3852 hci_change_link_key_complete_evt(hdev, skb);
3853 break;
3854
3855 case HCI_EV_REMOTE_FEATURES:
3856 hci_remote_features_evt(hdev, skb);
3857 break;
3858
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003859 case HCI_EV_CMD_COMPLETE:
3860 hci_cmd_complete_evt(hdev, skb);
3861 break;
3862
3863 case HCI_EV_CMD_STATUS:
3864 hci_cmd_status_evt(hdev, skb);
3865 break;
3866
3867 case HCI_EV_ROLE_CHANGE:
3868 hci_role_change_evt(hdev, skb);
3869 break;
3870
3871 case HCI_EV_NUM_COMP_PKTS:
3872 hci_num_comp_pkts_evt(hdev, skb);
3873 break;
3874
3875 case HCI_EV_MODE_CHANGE:
3876 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003877 break;
3878
3879 case HCI_EV_PIN_CODE_REQ:
3880 hci_pin_code_request_evt(hdev, skb);
3881 break;
3882
3883 case HCI_EV_LINK_KEY_REQ:
3884 hci_link_key_request_evt(hdev, skb);
3885 break;
3886
3887 case HCI_EV_LINK_KEY_NOTIFY:
3888 hci_link_key_notify_evt(hdev, skb);
3889 break;
3890
3891 case HCI_EV_CLOCK_OFFSET:
3892 hci_clock_offset_evt(hdev, skb);
3893 break;
3894
Marcel Holtmanna8746412008-07-14 20:13:46 +02003895 case HCI_EV_PKT_TYPE_CHANGE:
3896 hci_pkt_type_change_evt(hdev, skb);
3897 break;
3898
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003899 case HCI_EV_PSCAN_REP_MODE:
3900 hci_pscan_rep_mode_evt(hdev, skb);
3901 break;
3902
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003903 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3904 hci_inquiry_result_with_rssi_evt(hdev, skb);
3905 break;
3906
3907 case HCI_EV_REMOTE_EXT_FEATURES:
3908 hci_remote_ext_features_evt(hdev, skb);
3909 break;
3910
3911 case HCI_EV_SYNC_CONN_COMPLETE:
3912 hci_sync_conn_complete_evt(hdev, skb);
3913 break;
3914
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003915 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3916 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917 break;
3918
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003919 case HCI_EV_KEY_REFRESH_COMPLETE:
3920 hci_key_refresh_complete_evt(hdev, skb);
3921 break;
3922
Marcel Holtmann04936842008-07-14 20:13:48 +02003923 case HCI_EV_IO_CAPA_REQUEST:
3924 hci_io_capa_request_evt(hdev, skb);
3925 break;
3926
Johan Hedberg03b555e2011-01-04 15:40:05 +02003927 case HCI_EV_IO_CAPA_REPLY:
3928 hci_io_capa_reply_evt(hdev, skb);
3929 break;
3930
Johan Hedberga5c29682011-02-19 12:05:57 -03003931 case HCI_EV_USER_CONFIRM_REQUEST:
3932 hci_user_confirm_request_evt(hdev, skb);
3933 break;
3934
Brian Gix1143d452011-11-23 08:28:34 -08003935 case HCI_EV_USER_PASSKEY_REQUEST:
3936 hci_user_passkey_request_evt(hdev, skb);
3937 break;
3938
Johan Hedberg92a25252012-09-06 18:39:26 +03003939 case HCI_EV_USER_PASSKEY_NOTIFY:
3940 hci_user_passkey_notify_evt(hdev, skb);
3941 break;
3942
3943 case HCI_EV_KEYPRESS_NOTIFY:
3944 hci_keypress_notify_evt(hdev, skb);
3945 break;
3946
Marcel Holtmann04936842008-07-14 20:13:48 +02003947 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3948 hci_simple_pair_complete_evt(hdev, skb);
3949 break;
3950
Marcel Holtmann41a96212008-07-14 20:13:48 +02003951 case HCI_EV_REMOTE_HOST_FEATURES:
3952 hci_remote_host_features_evt(hdev, skb);
3953 break;
3954
Ville Tervofcd89c02011-02-10 22:38:47 -03003955 case HCI_EV_LE_META:
3956 hci_le_meta_evt(hdev, skb);
3957 break;
3958
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003959 case HCI_EV_CHANNEL_SELECTED:
3960 hci_chan_selected_evt(hdev, skb);
3961 break;
3962
Szymon Janc2763eda2011-03-22 13:12:22 +01003963 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3964 hci_remote_oob_data_request_evt(hdev, skb);
3965 break;
3966
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003967 case HCI_EV_PHY_LINK_COMPLETE:
3968 hci_phy_link_complete_evt(hdev, skb);
3969 break;
3970
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003971 case HCI_EV_LOGICAL_LINK_COMPLETE:
3972 hci_loglink_complete_evt(hdev, skb);
3973 break;
3974
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003975 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3976 hci_disconn_loglink_complete_evt(hdev, skb);
3977 break;
3978
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003979 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3980 hci_disconn_phylink_complete_evt(hdev, skb);
3981 break;
3982
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003983 case HCI_EV_NUM_COMP_BLOCKS:
3984 hci_num_comp_blocks_evt(hdev, skb);
3985 break;
3986
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003987 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003988 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003989 break;
3990 }
3991
3992 kfree_skb(skb);
3993 hdev->stat.evt_rx++;
3994}