blob: 74014420b3c7daff29c2ebbfb8fa228efac3aa78 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <asm/unaligned.h>
28
29#include <net/bluetooth/bluetooth.h>
30#include <net/bluetooth/hci_core.h>
Mikel Astizf0d6a0e2012-08-09 09:52:30 +020031#include <net/bluetooth/mgmt.h>
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070032
Marcel Holtmann70247282013-10-10 14:54:15 -070033#include "a2mp.h"
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070034#include "amp.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
Linus Torvalds1da177e2005-04-16 15:20:36 -070036/* Handle HCI Event packets */
37
Marcel Holtmanna9de9242007-10-20 13:33:56 +020038static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070039{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020040 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030042 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
Andre Guedes82f47852013-04-30 15:29:34 -030044 if (status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020045 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
Andre Guedes89352e72011-11-04 14:16:53 -030047 clear_bit(HCI_INQUIRY, &hdev->flags);
Peter Zijlstra4e857c52014-03-17 18:06:10 +010048 smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
Andre Guedes3e13fa12013-03-27 20:04:56 -030049 wake_up_bit(&hdev->flags, HCI_INQUIRY);
Andre Guedes89352e72011-11-04 14:16:53 -030050
Marcel Holtmanna9de9242007-10-20 13:33:56 +020051 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070052}
53
Andre Guedes4d934832012-03-21 00:03:35 -030054static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
55{
56 __u8 status = *((__u8 *) skb->data);
57
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030058 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesae854a72012-03-21 00:03:36 -030059
60 if (status)
61 return;
62
63 set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
Andre Guedes4d934832012-03-21 00:03:35 -030064}
65
Marcel Holtmanna9de9242007-10-20 13:33:56 +020066static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020068 __u8 status = *((__u8 *) skb->data);
69
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030070 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020071
72 if (status)
73 return;
74
Andre Guedesae854a72012-03-21 00:03:36 -030075 clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
76
Marcel Holtmanna9de9242007-10-20 13:33:56 +020077 hci_conn_check_pending(hdev);
78}
79
Gustavo Padovan807deac2012-05-17 00:36:24 -030080static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
81 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020082{
83 BT_DBG("%s", hdev->name);
84}
85
86static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
87{
88 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030091 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
Marcel Holtmanna9de9242007-10-20 13:33:56 +020093 if (rp->status)
94 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
Marcel Holtmanna9de9242007-10-20 13:33:56 +020096 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Marcel Holtmanna9de9242007-10-20 13:33:56 +020098 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
99 if (conn) {
100 if (rp->role)
101 conn->link_mode &= ~HCI_LM_MASTER;
102 else
103 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200105
106 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107}
108
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200109static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
110{
111 struct hci_rp_read_link_policy *rp = (void *) skb->data;
112 struct hci_conn *conn;
113
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300114 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200115
116 if (rp->status)
117 return;
118
119 hci_dev_lock(hdev);
120
121 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
122 if (conn)
123 conn->link_policy = __le16_to_cpu(rp->policy);
124
125 hci_dev_unlock(hdev);
126}
127
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200128static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200130 struct hci_rp_write_link_policy *rp = (void *) skb->data;
131 struct hci_conn *conn;
132 void *sent;
133
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300134 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200135
136 if (rp->status)
137 return;
138
139 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
140 if (!sent)
141 return;
142
143 hci_dev_lock(hdev);
144
145 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200146 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700147 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200148
149 hci_dev_unlock(hdev);
150}
151
Gustavo Padovan807deac2012-05-17 00:36:24 -0300152static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
153 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200154{
155 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
156
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300157 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200158
159 if (rp->status)
160 return;
161
162 hdev->link_policy = __le16_to_cpu(rp->policy);
163}
164
Gustavo Padovan807deac2012-05-17 00:36:24 -0300165static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
166 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200167{
168 __u8 status = *((__u8 *) skb->data);
169 void *sent;
170
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300171 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200172
173 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
174 if (!sent)
175 return;
176
177 if (!status)
178 hdev->link_policy = get_unaligned_le16(sent);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200179}
180
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200181static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
182{
183 __u8 status = *((__u8 *) skb->data);
184
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300185 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200186
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300187 clear_bit(HCI_RESET, &hdev->flags);
188
Johan Hedberga297e972012-02-21 17:55:47 +0200189 /* Reset all non-persistent flags */
Johan Hedberg2cc6fb02013-03-15 17:06:57 -0500190 hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
Andre Guedes69775ff2012-02-23 16:50:05 +0200191
192 hdev->discovery.state = DISCOVERY_STOPPED;
Johan Hedbergbbaf4442012-11-08 01:22:59 +0100193 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
194 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100195
196 memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
197 hdev->adv_data_len = 0;
Marcel Holtmannf8e808b2013-10-16 00:16:47 -0700198
199 memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
200 hdev->scan_rsp_data_len = 0;
Marcel Holtmann06f5b772013-10-19 07:09:11 -0700201
Marcel Holtmann533553f2014-03-21 12:18:10 -0700202 hdev->le_scan_type = LE_SCAN_PASSIVE;
203
Marcel Holtmann06f5b772013-10-19 07:09:11 -0700204 hdev->ssp_debug_mode = 0;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200205}
206
207static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
208{
209 __u8 status = *((__u8 *) skb->data);
210 void *sent;
211
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300212 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200213
214 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
215 if (!sent)
216 return;
217
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200218 hci_dev_lock(hdev);
219
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200220 if (test_bit(HCI_MGMT, &hdev->dev_flags))
221 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200222 else if (!status)
223 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200224
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200225 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200226}
227
228static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
229{
230 struct hci_rp_read_local_name *rp = (void *) skb->data;
231
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300232 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200233
234 if (rp->status)
235 return;
236
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200237 if (test_bit(HCI_SETUP, &hdev->dev_flags))
238 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200239}
240
241static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
242{
243 __u8 status = *((__u8 *) skb->data);
244 void *sent;
245
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300246 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200247
248 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
249 if (!sent)
250 return;
251
252 if (!status) {
253 __u8 param = *((__u8 *) sent);
254
255 if (param == AUTH_ENABLED)
256 set_bit(HCI_AUTH, &hdev->flags);
257 else
258 clear_bit(HCI_AUTH, &hdev->flags);
259 }
260
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200261 if (test_bit(HCI_MGMT, &hdev->dev_flags))
262 mgmt_auth_enable_complete(hdev, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200263}
264
265static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
266{
267 __u8 status = *((__u8 *) skb->data);
268 void *sent;
269
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300270 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200271
272 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
273 if (!sent)
274 return;
275
276 if (!status) {
277 __u8 param = *((__u8 *) sent);
278
279 if (param)
280 set_bit(HCI_ENCRYPT, &hdev->flags);
281 else
282 clear_bit(HCI_ENCRYPT, &hdev->flags);
283 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200284}
285
286static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
287{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200288 __u8 param, status = *((__u8 *) skb->data);
289 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200290 void *sent;
291
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300292 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200293
294 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
295 if (!sent)
296 return;
297
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200298 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200299
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200300 hci_dev_lock(hdev);
301
Mikel Astizfa1bd912012-08-09 09:52:29 +0200302 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200303 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200304 hdev->discov_timeout = 0;
305 goto done;
306 }
307
Johan Hedberg0663ca22013-10-02 13:43:14 +0300308 /* We need to ensure that we set this back on if someone changed
309 * the scan mode through a raw HCI socket.
310 */
311 set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
312
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200313 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
314 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200315
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200316 if (param & SCAN_INQUIRY) {
317 set_bit(HCI_ISCAN, &hdev->flags);
318 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200319 mgmt_discoverable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200320 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200321 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200322
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200323 if (param & SCAN_PAGE) {
324 set_bit(HCI_PSCAN, &hdev->flags);
325 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200326 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200327 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200328 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200329
330done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200331 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200332}
333
334static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
335{
336 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
337
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300338 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200339
340 if (rp->status)
341 return;
342
343 memcpy(hdev->dev_class, rp->dev_class, 3);
344
345 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300346 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200347}
348
349static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
350{
351 __u8 status = *((__u8 *) skb->data);
352 void *sent;
353
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300354 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200355
356 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
357 if (!sent)
358 return;
359
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100360 hci_dev_lock(hdev);
361
362 if (status == 0)
363 memcpy(hdev->dev_class, sent, 3);
364
365 if (test_bit(HCI_MGMT, &hdev->dev_flags))
366 mgmt_set_class_of_dev_complete(hdev, sent, status);
367
368 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200369}
370
371static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
372{
373 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200375
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300376 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200377
378 if (rp->status)
379 return;
380
381 setting = __le16_to_cpu(rp->voice_setting);
382
Marcel Holtmannf383f272008-07-14 20:13:47 +0200383 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200384 return;
385
386 hdev->voice_setting = setting;
387
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300388 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200390 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200391 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392}
393
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300394static void hci_cc_write_voice_setting(struct hci_dev *hdev,
395 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200396{
397 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200398 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 void *sent;
400
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300401 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
Marcel Holtmannf383f272008-07-14 20:13:47 +0200403 if (status)
404 return;
405
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200406 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
407 if (!sent)
408 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
Marcel Holtmannf383f272008-07-14 20:13:47 +0200412 if (hdev->voice_setting == setting)
413 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Marcel Holtmannf383f272008-07-14 20:13:47 +0200415 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300417 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200418
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200419 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200420 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421}
422
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -0700423static void hci_cc_read_num_supported_iac(struct hci_dev *hdev,
424 struct sk_buff *skb)
425{
426 struct hci_rp_read_num_supported_iac *rp = (void *) skb->data;
427
428 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
429
430 if (rp->status)
431 return;
432
433 hdev->num_iac = rp->num_iac;
434
435 BT_DBG("%s num iac %d", hdev->name, hdev->num_iac);
436}
437
Marcel Holtmann333140b2008-07-14 20:13:48 +0200438static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
439{
440 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300441 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200442
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300443 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200444
Marcel Holtmann333140b2008-07-14 20:13:48 +0200445 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
446 if (!sent)
447 return;
448
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300449 if (!status) {
450 if (sent->mode)
Johan Hedbergcad718e2013-04-17 15:00:51 +0300451 hdev->features[1][0] |= LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300452 else
Johan Hedbergcad718e2013-04-17 15:00:51 +0300453 hdev->features[1][0] &= ~LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300454 }
455
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200456 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300457 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200458 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300459 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200460 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
461 else
462 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
463 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200464}
465
Marcel Holtmanneac83dc2014-01-10 02:07:23 -0800466static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb)
467{
468 u8 status = *((u8 *) skb->data);
469 struct hci_cp_write_sc_support *sent;
470
471 BT_DBG("%s status 0x%2.2x", hdev->name, status);
472
473 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
474 if (!sent)
475 return;
476
477 if (!status) {
478 if (sent->support)
479 hdev->features[1][0] |= LMP_HOST_SC;
480 else
481 hdev->features[1][0] &= ~LMP_HOST_SC;
482 }
483
484 if (test_bit(HCI_MGMT, &hdev->dev_flags))
485 mgmt_sc_enable_complete(hdev, sent->support, status);
486 else if (!status) {
487 if (sent->support)
488 set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
489 else
490 clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
491 }
492}
493
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200494static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
495{
496 struct hci_rp_read_local_version *rp = (void *) skb->data;
497
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300498 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200499
500 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200501 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200502
Marcel Holtmann0d5551f2013-10-18 12:04:50 -0700503 if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
504 hdev->hci_ver = rp->hci_ver;
505 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
506 hdev->lmp_ver = rp->lmp_ver;
507 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
508 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
509 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200510}
511
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300512static void hci_cc_read_local_commands(struct hci_dev *hdev,
513 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200514{
515 struct hci_rp_read_local_commands *rp = (void *) skb->data;
516
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300517 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200518
Marcel Holtmann6a070e62013-10-31 04:54:33 -0700519 if (rp->status)
520 return;
521
522 if (test_bit(HCI_SETUP, &hdev->dev_flags))
Johan Hedberg2177bab2013-03-05 20:37:43 +0200523 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200524}
525
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300526static void hci_cc_read_local_features(struct hci_dev *hdev,
527 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200528{
529 struct hci_rp_read_local_features *rp = (void *) skb->data;
530
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300531 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200532
533 if (rp->status)
534 return;
535
536 memcpy(hdev->features, rp->features, 8);
537
538 /* Adjust default settings according to features
539 * supported by device. */
540
Johan Hedbergcad718e2013-04-17 15:00:51 +0300541 if (hdev->features[0][0] & LMP_3SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200542 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
543
Johan Hedbergcad718e2013-04-17 15:00:51 +0300544 if (hdev->features[0][0] & LMP_5SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200545 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
546
Johan Hedbergcad718e2013-04-17 15:00:51 +0300547 if (hdev->features[0][1] & LMP_HV2) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200548 hdev->pkt_type |= (HCI_HV2);
549 hdev->esco_type |= (ESCO_HV2);
550 }
551
Johan Hedbergcad718e2013-04-17 15:00:51 +0300552 if (hdev->features[0][1] & LMP_HV3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200553 hdev->pkt_type |= (HCI_HV3);
554 hdev->esco_type |= (ESCO_HV3);
555 }
556
Andre Guedes45db810f2012-07-24 15:03:49 -0300557 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200558 hdev->esco_type |= (ESCO_EV3);
559
Johan Hedbergcad718e2013-04-17 15:00:51 +0300560 if (hdev->features[0][4] & LMP_EV4)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200561 hdev->esco_type |= (ESCO_EV4);
562
Johan Hedbergcad718e2013-04-17 15:00:51 +0300563 if (hdev->features[0][4] & LMP_EV5)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200564 hdev->esco_type |= (ESCO_EV5);
565
Johan Hedbergcad718e2013-04-17 15:00:51 +0300566 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100567 hdev->esco_type |= (ESCO_2EV3);
568
Johan Hedbergcad718e2013-04-17 15:00:51 +0300569 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100570 hdev->esco_type |= (ESCO_3EV3);
571
Johan Hedbergcad718e2013-04-17 15:00:51 +0300572 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100573 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200574}
575
Andre Guedes971e3a42011-06-30 19:20:52 -0300576static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300577 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300578{
579 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
580
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300581 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300582
583 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200584 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300585
Marcel Holtmann57af75a2013-10-18 12:04:47 -0700586 if (hdev->max_page < rp->max_page)
587 hdev->max_page = rp->max_page;
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300588
Johan Hedbergcad718e2013-04-17 15:00:51 +0300589 if (rp->page < HCI_MAX_PAGES)
590 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300591}
592
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200593static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300594 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200595{
596 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
597
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300598 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200599
Johan Hedberg42c6b122013-03-05 20:37:49 +0200600 if (!rp->status)
601 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200602}
603
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200604static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
605{
606 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
607
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300608 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200609
610 if (rp->status)
611 return;
612
613 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
614 hdev->sco_mtu = rp->sco_mtu;
615 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
616 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
617
618 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
619 hdev->sco_mtu = 64;
620 hdev->sco_pkts = 8;
621 }
622
623 hdev->acl_cnt = hdev->acl_pkts;
624 hdev->sco_cnt = hdev->sco_pkts;
625
Gustavo Padovan807deac2012-05-17 00:36:24 -0300626 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
627 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200628}
629
630static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
631{
632 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
633
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300634 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200635
636 if (!rp->status)
637 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200638}
639
Johan Hedbergf332ec62013-03-15 17:07:11 -0500640static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
641 struct sk_buff *skb)
642{
643 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
644
645 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
646
647 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
648 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
649 hdev->page_scan_window = __le16_to_cpu(rp->window);
650 }
651}
652
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500653static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
654 struct sk_buff *skb)
655{
656 u8 status = *((u8 *) skb->data);
657 struct hci_cp_write_page_scan_activity *sent;
658
659 BT_DBG("%s status 0x%2.2x", hdev->name, status);
660
661 if (status)
662 return;
663
664 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
665 if (!sent)
666 return;
667
668 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
669 hdev->page_scan_window = __le16_to_cpu(sent->window);
670}
671
Johan Hedbergf332ec62013-03-15 17:07:11 -0500672static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
673 struct sk_buff *skb)
674{
675 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
676
677 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
678
679 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
680 hdev->page_scan_type = rp->type;
681}
682
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500683static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
684 struct sk_buff *skb)
685{
686 u8 status = *((u8 *) skb->data);
687 u8 *type;
688
689 BT_DBG("%s status 0x%2.2x", hdev->name, status);
690
691 if (status)
692 return;
693
694 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
695 if (type)
696 hdev->page_scan_type = *type;
697}
698
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200699static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300700 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200701{
702 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
703
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300704 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200705
706 if (rp->status)
707 return;
708
709 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
710 hdev->block_len = __le16_to_cpu(rp->block_len);
711 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
712
713 hdev->block_cnt = hdev->num_blocks;
714
715 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300716 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200717}
718
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300719static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300720 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300721{
722 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
723
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300724 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300725
726 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300727 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300728
729 hdev->amp_status = rp->amp_status;
730 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
731 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
732 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
733 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
734 hdev->amp_type = rp->amp_type;
735 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
736 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
737 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
738 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
739
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300740a2mp_rsp:
741 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300742}
743
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300744static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
745 struct sk_buff *skb)
746{
747 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
748 struct amp_assoc *assoc = &hdev->loc_assoc;
749 size_t rem_len, frag_len;
750
751 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
752
753 if (rp->status)
754 goto a2mp_rsp;
755
756 frag_len = skb->len - sizeof(*rp);
757 rem_len = __le16_to_cpu(rp->rem_len);
758
759 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300760 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300761
762 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
763 assoc->offset += frag_len;
764
765 /* Read other fragments */
766 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
767
768 return;
769 }
770
771 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
772 assoc->len = assoc->offset + rem_len;
773 assoc->offset = 0;
774
775a2mp_rsp:
776 /* Send A2MP Rsp when all fragments are received */
777 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300778 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300779}
780
Johan Hedbergd5859e22011-01-25 01:19:58 +0200781static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300782 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200783{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700784 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200785
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300786 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200787
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700788 if (!rp->status)
789 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200790}
791
Johan Hedberg980e1a52011-01-22 06:10:07 +0200792static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
793{
794 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
795 struct hci_cp_pin_code_reply *cp;
796 struct hci_conn *conn;
797
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300798 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200799
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200800 hci_dev_lock(hdev);
801
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200802 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200803 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200804
Mikel Astizfa1bd912012-08-09 09:52:29 +0200805 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200806 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200807
808 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
809 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200810 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200811
812 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
813 if (conn)
814 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200815
816unlock:
817 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200818}
819
820static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
821{
822 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
823
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300824 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200825
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200826 hci_dev_lock(hdev);
827
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200828 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200829 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300830 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200831
832 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200833}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200834
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300835static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
836 struct sk_buff *skb)
837{
838 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
839
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300840 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300841
842 if (rp->status)
843 return;
844
845 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
846 hdev->le_pkts = rp->le_max_pkt;
847
848 hdev->le_cnt = hdev->le_pkts;
849
850 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300851}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200852
Johan Hedberg60e77322013-01-22 14:01:59 +0200853static void hci_cc_le_read_local_features(struct hci_dev *hdev,
854 struct sk_buff *skb)
855{
856 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
857
858 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
859
860 if (!rp->status)
861 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200862}
863
Johan Hedberg8fa19092012-10-19 20:57:49 +0300864static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
865 struct sk_buff *skb)
866{
867 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
868
869 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
870
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500871 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300872 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300873}
874
Johan Hedberga5c29682011-02-19 12:05:57 -0300875static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
876{
877 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
878
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300879 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300880
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200881 hci_dev_lock(hdev);
882
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200883 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300884 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
885 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200886
887 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300888}
889
890static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300891 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300892{
893 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
894
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300895 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300896
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200897 hci_dev_lock(hdev);
898
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200899 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200900 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300901 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200902
903 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300904}
905
Brian Gix1143d452011-11-23 08:28:34 -0800906static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
907{
908 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
909
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300910 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800911
912 hci_dev_lock(hdev);
913
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200914 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200915 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300916 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800917
918 hci_dev_unlock(hdev);
919}
920
921static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300922 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800923{
924 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
925
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300926 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800927
928 hci_dev_lock(hdev);
929
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200930 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800931 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300932 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800933
934 hci_dev_unlock(hdev);
935}
936
Marcel Holtmann4d2d2792014-01-10 02:07:26 -0800937static void hci_cc_read_local_oob_data(struct hci_dev *hdev,
938 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100939{
940 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
941
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300942 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100943
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200944 hci_dev_lock(hdev);
Marcel Holtmann4d2d2792014-01-10 02:07:26 -0800945 mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->randomizer,
946 NULL, NULL, rp->status);
947 hci_dev_unlock(hdev);
948}
949
950static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev,
951 struct sk_buff *skb)
952{
953 struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data;
954
955 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
956
957 hci_dev_lock(hdev);
958 mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->randomizer192,
959 rp->hash256, rp->randomizer256,
960 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200961 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100962}
963
Marcel Holtmann7a4cd512014-02-19 19:52:13 -0800964
965static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb)
966{
967 __u8 status = *((__u8 *) skb->data);
968 bdaddr_t *sent;
969
970 BT_DBG("%s status 0x%2.2x", hdev->name, status);
971
972 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
973 if (!sent)
974 return;
975
976 hci_dev_lock(hdev);
977
978 if (!status)
979 bacpy(&hdev->random_addr, sent);
980
981 hci_dev_unlock(hdev);
982}
983
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100984static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
985{
986 __u8 *sent, status = *((__u8 *) skb->data);
987
988 BT_DBG("%s status 0x%2.2x", hdev->name, status);
989
990 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
991 if (!sent)
992 return;
993
994 hci_dev_lock(hdev);
995
Johan Hedberg778b2352014-02-24 14:52:17 +0200996 if (!status)
997 mgmt_advertising(hdev, *sent);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100998
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500999 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01001000}
1001
Marcel Holtmann533553f2014-03-21 12:18:10 -07001002static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1003{
1004 struct hci_cp_le_set_scan_param *cp;
1005 __u8 status = *((__u8 *) skb->data);
1006
1007 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1008
1009 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_PARAM);
1010 if (!cp)
1011 return;
1012
1013 hci_dev_lock(hdev);
1014
1015 if (!status)
1016 hdev->le_scan_type = cp->type;
1017
1018 hci_dev_unlock(hdev);
1019}
1020
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001021static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001022 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001023{
1024 struct hci_cp_le_set_scan_enable *cp;
1025 __u8 status = *((__u8 *) skb->data);
1026
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001027 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001028
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001029 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1030 if (!cp)
1031 return;
1032
Andre Guedes3fd319b2013-04-30 15:29:36 -03001033 if (status)
1034 return;
1035
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001036 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -03001037 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -03001038 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001039 break;
1040
Andre Guedes76a388b2013-04-04 20:21:02 -03001041 case LE_SCAN_DISABLE:
Johan Hedberg317ac8c2014-02-28 20:26:12 +02001042 /* Cancel this timer so that we don't try to disable scanning
1043 * when it's already disabled.
1044 */
1045 cancel_delayed_work(&hdev->le_scan_disable);
1046
Andre Guedesd23264a2011-11-25 20:53:38 -03001047 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Johan Hedberg81ad6fd2014-02-28 20:26:13 +02001048 /* The HCI_LE_SCAN_INTERRUPTED flag indicates that we
1049 * interrupted scanning due to a connect request. Mark
1050 * therefore discovery as stopped.
1051 */
1052 if (test_and_clear_bit(HCI_LE_SCAN_INTERRUPTED,
1053 &hdev->dev_flags))
1054 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001055 break;
1056
1057 default:
1058 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1059 break;
Andre Guedes35815082011-05-26 16:23:53 -03001060 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001061}
1062
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001063static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
1064 struct sk_buff *skb)
1065{
1066 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
1067
1068 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
1069
1070 if (!rp->status)
1071 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001072}
1073
Marcel Holtmann0f36b582014-02-27 20:37:31 -08001074static void hci_cc_le_clear_white_list(struct hci_dev *hdev,
1075 struct sk_buff *skb)
1076{
1077 __u8 status = *((__u8 *) skb->data);
1078
1079 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1080
1081 if (!status)
1082 hci_white_list_clear(hdev);
1083}
1084
1085static void hci_cc_le_add_to_white_list(struct hci_dev *hdev,
1086 struct sk_buff *skb)
1087{
1088 struct hci_cp_le_add_to_white_list *sent;
1089 __u8 status = *((__u8 *) skb->data);
1090
1091 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1092
1093 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST);
1094 if (!sent)
1095 return;
1096
1097 if (!status)
1098 hci_white_list_add(hdev, &sent->bdaddr, sent->bdaddr_type);
1099}
1100
1101static void hci_cc_le_del_from_white_list(struct hci_dev *hdev,
1102 struct sk_buff *skb)
1103{
1104 struct hci_cp_le_del_from_white_list *sent;
1105 __u8 status = *((__u8 *) skb->data);
1106
1107 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1108
1109 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST);
1110 if (!sent)
1111 return;
1112
1113 if (!status)
1114 hci_white_list_del(hdev, &sent->bdaddr, sent->bdaddr_type);
1115}
1116
Johan Hedberg9b008c02013-01-22 14:02:01 +02001117static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
1118 struct sk_buff *skb)
1119{
1120 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
1121
1122 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1123
1124 if (!rp->status)
1125 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +02001126}
1127
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001128static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1129 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001130{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001131 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001132 __u8 status = *((__u8 *) skb->data);
1133
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001134 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001135
Johan Hedberg06199cf2012-02-22 16:37:11 +02001136 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001137 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001138 return;
1139
Johan Hedberg8f984df2012-02-28 01:07:22 +02001140 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001141 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001142 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001143 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1144 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001145 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001146 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001147 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001148 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001149
1150 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001151 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001152 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001153 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001154 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001155}
1156
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02001157static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
1158{
1159 struct hci_cp_le_set_adv_param *cp;
1160 u8 status = *((u8 *) skb->data);
1161
1162 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1163
1164 if (status)
1165 return;
1166
1167 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM);
1168 if (!cp)
1169 return;
1170
1171 hci_dev_lock(hdev);
1172 hdev->adv_addr_type = cp->own_address_type;
1173 hci_dev_unlock(hdev);
1174}
1175
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001176static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1177 struct sk_buff *skb)
1178{
1179 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1180
1181 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1182 hdev->name, rp->status, rp->phy_handle);
1183
1184 if (rp->status)
1185 return;
1186
1187 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1188}
1189
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001190static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001191{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001192 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001193
1194 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001195 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001196 return;
1197 }
1198
Andre Guedes89352e72011-11-04 14:16:53 -03001199 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001200}
1201
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001202static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001204 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001207 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001208
1209 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 if (!cp)
1211 return;
1212
1213 hci_dev_lock(hdev);
1214
1215 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1216
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001217 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218
1219 if (status) {
1220 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001221 if (status != 0x0c || conn->attempt > 2) {
1222 conn->state = BT_CLOSED;
1223 hci_proto_connect_cfm(conn, status);
1224 hci_conn_del(conn);
1225 } else
1226 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001227 }
1228 } else {
1229 if (!conn) {
1230 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1231 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001232 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233 conn->link_mode |= HCI_LM_MASTER;
1234 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001235 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 }
1237 }
1238
1239 hci_dev_unlock(hdev);
1240}
1241
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001242static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001244 struct hci_cp_add_sco *cp;
1245 struct hci_conn *acl, *sco;
1246 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001248 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001249
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001250 if (!status)
1251 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001253 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1254 if (!cp)
1255 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001257 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001259 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001260
1261 hci_dev_lock(hdev);
1262
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001263 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001264 if (acl) {
1265 sco = acl->link;
1266 if (sco) {
1267 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001268
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001269 hci_proto_connect_cfm(sco, status);
1270 hci_conn_del(sco);
1271 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001272 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001273
1274 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275}
1276
Marcel Holtmannf8558552008-07-14 20:13:49 +02001277static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1278{
1279 struct hci_cp_auth_requested *cp;
1280 struct hci_conn *conn;
1281
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001282 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001283
1284 if (!status)
1285 return;
1286
1287 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1288 if (!cp)
1289 return;
1290
1291 hci_dev_lock(hdev);
1292
1293 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1294 if (conn) {
1295 if (conn->state == BT_CONFIG) {
1296 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001297 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001298 }
1299 }
1300
1301 hci_dev_unlock(hdev);
1302}
1303
1304static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1305{
1306 struct hci_cp_set_conn_encrypt *cp;
1307 struct hci_conn *conn;
1308
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001309 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001310
1311 if (!status)
1312 return;
1313
1314 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1315 if (!cp)
1316 return;
1317
1318 hci_dev_lock(hdev);
1319
1320 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1321 if (conn) {
1322 if (conn->state == BT_CONFIG) {
1323 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001324 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001325 }
1326 }
1327
1328 hci_dev_unlock(hdev);
1329}
1330
Johan Hedberg127178d2010-11-18 22:22:29 +02001331static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001332 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001333{
Johan Hedberg392599b2010-11-18 22:22:28 +02001334 if (conn->state != BT_CONFIG || !conn->out)
1335 return 0;
1336
Johan Hedberg765c2a92011-01-19 12:06:52 +05301337 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001338 return 0;
1339
1340 /* Only request authentication for SSP connections or non-SSP
Johan Hedberg264b8b42014-01-08 16:40:39 +02001341 * devices with sec_level MEDIUM or HIGH or if MITM protection
1342 * is requested.
1343 */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001344 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
Johan Hedberg264b8b42014-01-08 16:40:39 +02001345 conn->pending_sec_level != BT_SECURITY_HIGH &&
1346 conn->pending_sec_level != BT_SECURITY_MEDIUM)
Johan Hedberg392599b2010-11-18 22:22:28 +02001347 return 0;
1348
Johan Hedberg392599b2010-11-18 22:22:28 +02001349 return 1;
1350}
1351
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001352static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001353 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001354{
1355 struct hci_cp_remote_name_req cp;
1356
1357 memset(&cp, 0, sizeof(cp));
1358
1359 bacpy(&cp.bdaddr, &e->data.bdaddr);
1360 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1361 cp.pscan_mode = e->data.pscan_mode;
1362 cp.clock_offset = e->data.clock_offset;
1363
1364 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1365}
1366
Johan Hedbergb644ba32012-01-17 21:48:47 +02001367static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001368{
1369 struct discovery_state *discov = &hdev->discovery;
1370 struct inquiry_entry *e;
1371
Johan Hedbergb644ba32012-01-17 21:48:47 +02001372 if (list_empty(&discov->resolve))
1373 return false;
1374
1375 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001376 if (!e)
1377 return false;
1378
Johan Hedbergb644ba32012-01-17 21:48:47 +02001379 if (hci_resolve_name(hdev, e) == 0) {
1380 e->name_state = NAME_PENDING;
1381 return true;
1382 }
1383
1384 return false;
1385}
1386
1387static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001388 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001389{
1390 struct discovery_state *discov = &hdev->discovery;
1391 struct inquiry_entry *e;
1392
1393 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001394 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1395 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001396
1397 if (discov->state == DISCOVERY_STOPPED)
1398 return;
1399
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001400 if (discov->state == DISCOVERY_STOPPING)
1401 goto discov_complete;
1402
1403 if (discov->state != DISCOVERY_RESOLVING)
1404 return;
1405
1406 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001407 /* If the device was not found in a list of found devices names of which
1408 * are pending. there is no need to continue resolving a next name as it
1409 * will be done upon receiving another Remote Name Request Complete
1410 * Event */
1411 if (!e)
1412 return;
1413
1414 list_del(&e->list);
1415 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001416 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001417 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1418 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001419 } else {
1420 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001421 }
1422
Johan Hedbergb644ba32012-01-17 21:48:47 +02001423 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001424 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001425
1426discov_complete:
1427 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1428}
1429
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001430static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1431{
Johan Hedberg127178d2010-11-18 22:22:29 +02001432 struct hci_cp_remote_name_req *cp;
1433 struct hci_conn *conn;
1434
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001435 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001436
1437 /* If successful wait for the name req complete event before
1438 * checking for the need to do authentication */
1439 if (!status)
1440 return;
1441
1442 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1443 if (!cp)
1444 return;
1445
1446 hci_dev_lock(hdev);
1447
1448 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001449
1450 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1451 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1452
Johan Hedberg79c6c702011-04-28 11:28:55 -07001453 if (!conn)
1454 goto unlock;
1455
1456 if (!hci_outgoing_auth_needed(hdev, conn))
1457 goto unlock;
1458
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001459 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001460 struct hci_cp_auth_requested auth_cp;
1461
1462 auth_cp.handle = __cpu_to_le16(conn->handle);
1463 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1464 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001465 }
1466
Johan Hedberg79c6c702011-04-28 11:28:55 -07001467unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001468 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001469}
1470
Marcel Holtmann769be972008-07-14 20:13:49 +02001471static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1472{
1473 struct hci_cp_read_remote_features *cp;
1474 struct hci_conn *conn;
1475
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001476 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001477
1478 if (!status)
1479 return;
1480
1481 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1482 if (!cp)
1483 return;
1484
1485 hci_dev_lock(hdev);
1486
1487 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1488 if (conn) {
1489 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001490 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001491 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001492 }
1493 }
1494
1495 hci_dev_unlock(hdev);
1496}
1497
1498static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1499{
1500 struct hci_cp_read_remote_ext_features *cp;
1501 struct hci_conn *conn;
1502
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001503 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001504
1505 if (!status)
1506 return;
1507
1508 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1509 if (!cp)
1510 return;
1511
1512 hci_dev_lock(hdev);
1513
1514 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1515 if (conn) {
1516 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001517 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001518 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001519 }
1520 }
1521
1522 hci_dev_unlock(hdev);
1523}
1524
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001525static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1526{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001527 struct hci_cp_setup_sync_conn *cp;
1528 struct hci_conn *acl, *sco;
1529 __u16 handle;
1530
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001531 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001532
1533 if (!status)
1534 return;
1535
1536 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1537 if (!cp)
1538 return;
1539
1540 handle = __le16_to_cpu(cp->handle);
1541
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001542 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001543
1544 hci_dev_lock(hdev);
1545
1546 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001547 if (acl) {
1548 sco = acl->link;
1549 if (sco) {
1550 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001551
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001552 hci_proto_connect_cfm(sco, status);
1553 hci_conn_del(sco);
1554 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001555 }
1556
1557 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001558}
1559
1560static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1561{
1562 struct hci_cp_sniff_mode *cp;
1563 struct hci_conn *conn;
1564
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001565 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001566
1567 if (!status)
1568 return;
1569
1570 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1571 if (!cp)
1572 return;
1573
1574 hci_dev_lock(hdev);
1575
1576 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001577 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001578 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001579
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001580 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001581 hci_sco_setup(conn, status);
1582 }
1583
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001584 hci_dev_unlock(hdev);
1585}
1586
1587static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1588{
1589 struct hci_cp_exit_sniff_mode *cp;
1590 struct hci_conn *conn;
1591
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001592 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001593
1594 if (!status)
1595 return;
1596
1597 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1598 if (!cp)
1599 return;
1600
1601 hci_dev_lock(hdev);
1602
1603 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001604 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001605 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001606
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001607 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001608 hci_sco_setup(conn, status);
1609 }
1610
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001611 hci_dev_unlock(hdev);
1612}
1613
Johan Hedberg88c3df12012-02-09 14:27:38 +02001614static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1615{
1616 struct hci_cp_disconnect *cp;
1617 struct hci_conn *conn;
1618
1619 if (!status)
1620 return;
1621
1622 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1623 if (!cp)
1624 return;
1625
1626 hci_dev_lock(hdev);
1627
1628 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1629 if (conn)
1630 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001631 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001632
1633 hci_dev_unlock(hdev);
1634}
1635
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001636static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1637{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001638 struct hci_cp_create_phy_link *cp;
1639
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001640 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001641
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001642 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1643 if (!cp)
1644 return;
1645
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001646 hci_dev_lock(hdev);
1647
1648 if (status) {
1649 struct hci_conn *hcon;
1650
1651 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1652 if (hcon)
1653 hci_conn_del(hcon);
1654 } else {
1655 amp_write_remote_assoc(hdev, cp->phy_handle);
1656 }
1657
1658 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001659}
1660
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001661static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1662{
1663 struct hci_cp_accept_phy_link *cp;
1664
1665 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1666
1667 if (status)
1668 return;
1669
1670 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1671 if (!cp)
1672 return;
1673
1674 amp_write_remote_assoc(hdev, cp->phy_handle);
1675}
1676
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02001677static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
1678{
1679 struct hci_cp_le_create_conn *cp;
1680 struct hci_conn *conn;
1681
1682 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1683
1684 /* All connection failure handling is taken care of by the
1685 * hci_le_conn_failed function which is triggered by the HCI
1686 * request completion callbacks used for connecting.
1687 */
1688 if (status)
1689 return;
1690
1691 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1692 if (!cp)
1693 return;
1694
1695 hci_dev_lock(hdev);
1696
1697 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1698 if (!conn)
1699 goto unlock;
1700
1701 /* Store the initiator and responder address information which
1702 * is needed for SMP. These values will not change during the
1703 * lifetime of the connection.
1704 */
1705 conn->init_addr_type = cp->own_address_type;
1706 if (cp->own_address_type == ADDR_LE_DEV_RANDOM)
1707 bacpy(&conn->init_addr, &hdev->random_addr);
1708 else
1709 bacpy(&conn->init_addr, &hdev->bdaddr);
1710
1711 conn->resp_addr_type = cp->peer_addr_type;
1712 bacpy(&conn->resp_addr, &cp->peer_addr);
1713
Johan Hedberg9489eca2014-02-28 17:45:46 +02001714 /* We don't want the connection attempt to stick around
1715 * indefinitely since LE doesn't have a page timeout concept
1716 * like BR/EDR. Set a timer for any connection that doesn't use
1717 * the white list for connecting.
1718 */
1719 if (cp->filter_policy == HCI_LE_USE_PEER_ADDR)
1720 queue_delayed_work(conn->hdev->workqueue,
1721 &conn->le_conn_timeout,
1722 HCI_LE_CONN_TIMEOUT);
1723
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02001724unlock:
1725 hci_dev_unlock(hdev);
1726}
1727
Johan Hedberg81d0c8a2014-03-24 14:39:04 +02001728static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1729{
1730 struct hci_cp_le_start_enc *cp;
1731 struct hci_conn *conn;
1732
1733 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1734
1735 if (!status)
1736 return;
1737
1738 hci_dev_lock(hdev);
1739
1740 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_START_ENC);
1741 if (!cp)
1742 goto unlock;
1743
1744 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1745 if (!conn)
1746 goto unlock;
1747
1748 if (conn->state != BT_CONNECTED)
1749 goto unlock;
1750
1751 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
1752 hci_conn_drop(conn);
1753
1754unlock:
1755 hci_dev_unlock(hdev);
1756}
1757
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001758static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001759{
1760 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001761 struct discovery_state *discov = &hdev->discovery;
1762 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001763
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001764 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001765
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001766 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001767
1768 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1769 return;
1770
Peter Zijlstra4e857c52014-03-17 18:06:10 +01001771 smp_mb__after_atomic(); /* wake_up_bit advises about this barrier */
Andre Guedes3e13fa12013-03-27 20:04:56 -03001772 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1773
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001774 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001775 return;
1776
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001777 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001778
Andre Guedes343f9352012-02-17 20:39:37 -03001779 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001780 goto unlock;
1781
1782 if (list_empty(&discov->resolve)) {
1783 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1784 goto unlock;
1785 }
1786
1787 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1788 if (e && hci_resolve_name(hdev, e) == 0) {
1789 e->name_state = NAME_PENDING;
1790 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1791 } else {
1792 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1793 }
1794
1795unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001796 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001797}
1798
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001799static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001801 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001802 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 int num_rsp = *((__u8 *) skb->data);
1804
1805 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1806
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001807 if (!num_rsp)
1808 return;
1809
Andre Guedes1519cc12012-03-21 00:03:38 -03001810 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1811 return;
1812
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001814
Johan Hedberge17acd42011-03-30 23:57:16 +03001815 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001816 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001817
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818 bacpy(&data.bdaddr, &info->bdaddr);
1819 data.pscan_rep_mode = info->pscan_rep_mode;
1820 data.pscan_period_mode = info->pscan_period_mode;
1821 data.pscan_mode = info->pscan_mode;
1822 memcpy(data.dev_class, info->dev_class, 3);
1823 data.clock_offset = info->clock_offset;
1824 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001825 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001826
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001827 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001828 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001829 info->dev_class, 0, !name_known, ssp, NULL,
1830 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001832
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 hci_dev_unlock(hdev);
1834}
1835
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001836static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001838 struct hci_ev_conn_complete *ev = (void *) skb->data;
1839 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001841 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001842
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001844
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001845 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001846 if (!conn) {
1847 if (ev->link_type != SCO_LINK)
1848 goto unlock;
1849
1850 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1851 if (!conn)
1852 goto unlock;
1853
1854 conn->type = SCO_LINK;
1855 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001856
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001857 if (!ev->status) {
1858 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001859
1860 if (conn->type == ACL_LINK) {
1861 conn->state = BT_CONFIG;
1862 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001863
1864 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1865 !hci_find_link_key(hdev, &ev->bdaddr))
1866 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1867 else
1868 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001869 } else
1870 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001871
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001872 hci_conn_add_sysfs(conn);
1873
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001874 if (test_bit(HCI_AUTH, &hdev->flags))
1875 conn->link_mode |= HCI_LM_AUTH;
1876
1877 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1878 conn->link_mode |= HCI_LM_ENCRYPT;
1879
1880 /* Get remote features */
1881 if (conn->type == ACL_LINK) {
1882 struct hci_cp_read_remote_features cp;
1883 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001884 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001885 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001886 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001887
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001888 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001889 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001890 struct hci_cp_change_conn_ptype cp;
1891 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001892 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001893 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1894 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001895 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001896 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001897 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001898 if (conn->type == ACL_LINK)
Marcel Holtmann64c7b772014-02-18 14:22:20 -08001899 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001900 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001901 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001902
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001903 if (conn->type == ACL_LINK)
1904 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001905
Marcel Holtmann769be972008-07-14 20:13:49 +02001906 if (ev->status) {
1907 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001908 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001909 } else if (ev->link_type != ACL_LINK)
1910 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001911
1912unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001914
1915 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916}
1917
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001918static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001920 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001922 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001924 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001925 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001927 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1928 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929
Szymon Janc138d22e2011-02-17 16:44:23 +01001930 if ((mask & HCI_LM_ACCEPT) &&
Marcel Holtmannb9ee0a72013-10-17 17:24:13 -07001931 !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001933 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935
1936 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001937
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001938 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1939 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001940 memcpy(ie->data.dev_class, ev->dev_class, 3);
1941
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001942 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1943 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001945 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1946 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001947 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948 hci_dev_unlock(hdev);
1949 return;
1950 }
1951 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001952
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001954
Linus Torvalds1da177e2005-04-16 15:20:36 -07001955 hci_dev_unlock(hdev);
1956
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001957 if (ev->link_type == ACL_LINK ||
1958 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001959 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001960 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001962 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001963
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001964 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1965 cp.role = 0x00; /* Become master */
1966 else
1967 cp.role = 0x01; /* Remain slave */
1968
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001969 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1970 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001971 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001972 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001973 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001974
1975 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001976 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001977
Joe Perchesdcf4adb2014-03-12 10:52:35 -07001978 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1979 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1980 cp.max_latency = cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001981 cp.content_format = cpu_to_le16(hdev->voice_setting);
1982 cp.retrans_effort = 0xff;
1983
1984 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001985 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001986 } else {
1987 conn->state = BT_CONNECT2;
1988 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001989 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001990 } else {
1991 /* Connection rejected */
1992 struct hci_cp_reject_conn_req cp;
1993
1994 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001995 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001996 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997 }
1998}
1999
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02002000static u8 hci_to_mgmt_reason(u8 err)
2001{
2002 switch (err) {
2003 case HCI_ERROR_CONNECTION_TIMEOUT:
2004 return MGMT_DEV_DISCONN_TIMEOUT;
2005 case HCI_ERROR_REMOTE_USER_TERM:
2006 case HCI_ERROR_REMOTE_LOW_RESOURCES:
2007 case HCI_ERROR_REMOTE_POWER_OFF:
2008 return MGMT_DEV_DISCONN_REMOTE;
2009 case HCI_ERROR_LOCAL_HOST_TERM:
2010 return MGMT_DEV_DISCONN_LOCAL_HOST;
2011 default:
2012 return MGMT_DEV_DISCONN_UNKNOWN;
2013 }
2014}
2015
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002016static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002018 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Andre Guedesabf54a52013-11-07 17:36:09 -03002019 u8 reason = hci_to_mgmt_reason(ev->reason);
Andre Guedes9fcb18e2014-02-26 20:21:48 -03002020 struct hci_conn_params *params;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002021 struct hci_conn *conn;
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02002022 bool mgmt_connected;
Andre Guedes38462202013-11-07 17:36:10 -03002023 u8 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002024
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002025 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002026
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027 hci_dev_lock(hdev);
2028
Marcel Holtmann04837f62006-07-03 10:02:33 +02002029 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02002030 if (!conn)
2031 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002032
Andre Guedesabf54a52013-11-07 17:36:09 -03002033 if (ev->status) {
2034 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
2035 conn->dst_type, ev->status);
2036 goto unlock;
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002037 }
Johan Hedbergf7520542011-01-20 12:34:39 +02002038
Andre Guedes38462202013-11-07 17:36:10 -03002039 conn->state = BT_CLOSED;
2040
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02002041 mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
2042 mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
2043 reason, mgmt_connected);
Andre Guedesabf54a52013-11-07 17:36:09 -03002044
Andre Guedes38462202013-11-07 17:36:10 -03002045 if (conn->type == ACL_LINK && conn->flush_key)
2046 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg22102462013-10-05 12:01:06 +02002047
Andre Guedes9fcb18e2014-02-26 20:21:48 -03002048 params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
2049 if (params) {
2050 switch (params->auto_connect) {
2051 case HCI_AUTO_CONN_LINK_LOSS:
2052 if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
2053 break;
2054 /* Fall through */
2055
2056 case HCI_AUTO_CONN_ALWAYS:
2057 hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type);
2058 break;
2059
2060 default:
2061 break;
2062 }
2063 }
2064
Andre Guedes38462202013-11-07 17:36:10 -03002065 type = conn->type;
Johan Hedberg22102462013-10-05 12:01:06 +02002066
Andre Guedes38462202013-11-07 17:36:10 -03002067 hci_proto_disconn_cfm(conn, ev->reason);
2068 hci_conn_del(conn);
2069
2070 /* Re-enable advertising if necessary, since it might
2071 * have been disabled by the connection. From the
2072 * HCI_LE_Set_Advertise_Enable command description in
2073 * the core specification (v4.0):
2074 * "The Controller shall continue advertising until the Host
2075 * issues an LE_Set_Advertise_Enable command with
2076 * Advertising_Enable set to 0x00 (Advertising is disabled)
2077 * or until a connection is created or until the Advertising
2078 * is timed out due to Directed Advertising."
2079 */
2080 if (type == LE_LINK)
2081 mgmt_reenable_advertising(hdev);
Johan Hedbergf7520542011-01-20 12:34:39 +02002082
2083unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002084 hci_dev_unlock(hdev);
2085}
2086
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002087static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002088{
2089 struct hci_ev_auth_complete *ev = (void *) skb->data;
2090 struct hci_conn *conn;
2091
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002092 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002093
2094 hci_dev_lock(hdev);
2095
2096 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002097 if (!conn)
2098 goto unlock;
2099
2100 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002101 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002102 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002103 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03002104 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002105 conn->link_mode |= HCI_LM_AUTH;
2106 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03002107 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002108 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02002109 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002110 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002111 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002112
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002113 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
2114 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002115
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002116 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002117 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002118 struct hci_cp_set_conn_encrypt cp;
2119 cp.handle = ev->handle;
2120 cp.encrypt = 0x01;
2121 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002122 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002123 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002124 conn->state = BT_CONNECTED;
2125 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002126 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002127 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002128 } else {
2129 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002130
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002131 hci_conn_hold(conn);
2132 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002133 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002134 }
2135
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002136 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002137 if (!ev->status) {
2138 struct hci_cp_set_conn_encrypt cp;
2139 cp.handle = ev->handle;
2140 cp.encrypt = 0x01;
2141 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002142 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002143 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002144 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002145 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002146 }
2147 }
2148
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002149unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002150 hci_dev_unlock(hdev);
2151}
2152
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002153static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002154{
Johan Hedberg127178d2010-11-18 22:22:29 +02002155 struct hci_ev_remote_name *ev = (void *) skb->data;
2156 struct hci_conn *conn;
2157
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002158 BT_DBG("%s", hdev->name);
2159
2160 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02002161
2162 hci_dev_lock(hdev);
2163
2164 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002165
2166 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2167 goto check_auth;
2168
2169 if (ev->status == 0)
2170 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002171 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002172 else
2173 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2174
2175check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002176 if (!conn)
2177 goto unlock;
2178
2179 if (!hci_outgoing_auth_needed(hdev, conn))
2180 goto unlock;
2181
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002182 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002183 struct hci_cp_auth_requested cp;
2184 cp.handle = __cpu_to_le16(conn->handle);
2185 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2186 }
2187
Johan Hedberg79c6c702011-04-28 11:28:55 -07002188unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002189 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002190}
2191
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002192static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002193{
2194 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2195 struct hci_conn *conn;
2196
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002197 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002198
2199 hci_dev_lock(hdev);
2200
2201 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002202 if (!conn)
2203 goto unlock;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002204
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002205 if (!ev->status) {
2206 if (ev->encrypt) {
2207 /* Encryption implies authentication */
2208 conn->link_mode |= HCI_LM_AUTH;
2209 conn->link_mode |= HCI_LM_ENCRYPT;
2210 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002211
Marcel Holtmann914a6ff2014-02-01 11:52:02 -08002212 /* P-256 authentication key implies FIPS */
2213 if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
2214 conn->link_mode |= HCI_LM_FIPS;
2215
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002216 if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
2217 conn->type == LE_LINK)
2218 set_bit(HCI_CONN_AES_CCM, &conn->flags);
2219 } else {
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002220 conn->link_mode &= ~HCI_LM_ENCRYPT;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002221 clear_bit(HCI_CONN_AES_CCM, &conn->flags);
2222 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002223 }
2224
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002225 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2226
2227 if (ev->status && conn->state == BT_CONNECTED) {
2228 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
2229 hci_conn_drop(conn);
2230 goto unlock;
2231 }
2232
2233 if (conn->state == BT_CONFIG) {
2234 if (!ev->status)
2235 conn->state = BT_CONNECTED;
2236
Marcel Holtmann40b552a2014-03-19 14:10:25 -07002237 /* In Secure Connections Only mode, do not allow any
2238 * connections that are not encrypted with AES-CCM
2239 * using a P-256 authenticated combination key.
2240 */
2241 if (test_bit(HCI_SC_ONLY, &hdev->dev_flags) &&
2242 (!test_bit(HCI_CONN_AES_CCM, &conn->flags) ||
2243 conn->key_type != HCI_LK_AUTH_COMBINATION_P256)) {
2244 hci_proto_connect_cfm(conn, HCI_ERROR_AUTH_FAILURE);
2245 hci_conn_drop(conn);
2246 goto unlock;
2247 }
2248
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002249 hci_proto_connect_cfm(conn, ev->status);
2250 hci_conn_drop(conn);
2251 } else
2252 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
2253
Gustavo Padovana7d77232012-05-13 03:20:07 -03002254unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002255 hci_dev_unlock(hdev);
2256}
2257
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002258static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2259 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002260{
2261 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2262 struct hci_conn *conn;
2263
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002264 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002265
2266 hci_dev_lock(hdev);
2267
2268 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2269 if (conn) {
2270 if (!ev->status)
2271 conn->link_mode |= HCI_LM_SECURE;
2272
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002273 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002274
2275 hci_key_change_cfm(conn, ev->status);
2276 }
2277
2278 hci_dev_unlock(hdev);
2279}
2280
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002281static void hci_remote_features_evt(struct hci_dev *hdev,
2282 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002283{
2284 struct hci_ev_remote_features *ev = (void *) skb->data;
2285 struct hci_conn *conn;
2286
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002287 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002288
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002289 hci_dev_lock(hdev);
2290
2291 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002292 if (!conn)
2293 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002294
Johan Hedbergccd556f2010-11-10 17:11:51 +02002295 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002296 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002297
2298 if (conn->state != BT_CONFIG)
2299 goto unlock;
2300
2301 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2302 struct hci_cp_read_remote_ext_features cp;
2303 cp.handle = ev->handle;
2304 cp.page = 0x01;
2305 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002306 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002307 goto unlock;
2308 }
2309
Johan Hedberg671267b2012-05-12 16:11:50 -03002310 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002311 struct hci_cp_remote_name_req cp;
2312 memset(&cp, 0, sizeof(cp));
2313 bacpy(&cp.bdaddr, &conn->dst);
2314 cp.pscan_rep_mode = 0x02;
2315 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002316 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2317 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002318 conn->dst_type, 0, NULL, 0,
2319 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002320
Johan Hedberg127178d2010-11-18 22:22:29 +02002321 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002322 conn->state = BT_CONNECTED;
2323 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002324 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002325 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002326
Johan Hedbergccd556f2010-11-10 17:11:51 +02002327unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002328 hci_dev_unlock(hdev);
2329}
2330
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002331static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002332{
2333 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002334 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002335 __u16 opcode;
2336
2337 skb_pull(skb, sizeof(*ev));
2338
2339 opcode = __le16_to_cpu(ev->opcode);
2340
2341 switch (opcode) {
2342 case HCI_OP_INQUIRY_CANCEL:
2343 hci_cc_inquiry_cancel(hdev, skb);
2344 break;
2345
Andre Guedes4d934832012-03-21 00:03:35 -03002346 case HCI_OP_PERIODIC_INQ:
2347 hci_cc_periodic_inq(hdev, skb);
2348 break;
2349
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002350 case HCI_OP_EXIT_PERIODIC_INQ:
2351 hci_cc_exit_periodic_inq(hdev, skb);
2352 break;
2353
2354 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2355 hci_cc_remote_name_req_cancel(hdev, skb);
2356 break;
2357
2358 case HCI_OP_ROLE_DISCOVERY:
2359 hci_cc_role_discovery(hdev, skb);
2360 break;
2361
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002362 case HCI_OP_READ_LINK_POLICY:
2363 hci_cc_read_link_policy(hdev, skb);
2364 break;
2365
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002366 case HCI_OP_WRITE_LINK_POLICY:
2367 hci_cc_write_link_policy(hdev, skb);
2368 break;
2369
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002370 case HCI_OP_READ_DEF_LINK_POLICY:
2371 hci_cc_read_def_link_policy(hdev, skb);
2372 break;
2373
2374 case HCI_OP_WRITE_DEF_LINK_POLICY:
2375 hci_cc_write_def_link_policy(hdev, skb);
2376 break;
2377
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002378 case HCI_OP_RESET:
2379 hci_cc_reset(hdev, skb);
2380 break;
2381
2382 case HCI_OP_WRITE_LOCAL_NAME:
2383 hci_cc_write_local_name(hdev, skb);
2384 break;
2385
2386 case HCI_OP_READ_LOCAL_NAME:
2387 hci_cc_read_local_name(hdev, skb);
2388 break;
2389
2390 case HCI_OP_WRITE_AUTH_ENABLE:
2391 hci_cc_write_auth_enable(hdev, skb);
2392 break;
2393
2394 case HCI_OP_WRITE_ENCRYPT_MODE:
2395 hci_cc_write_encrypt_mode(hdev, skb);
2396 break;
2397
2398 case HCI_OP_WRITE_SCAN_ENABLE:
2399 hci_cc_write_scan_enable(hdev, skb);
2400 break;
2401
2402 case HCI_OP_READ_CLASS_OF_DEV:
2403 hci_cc_read_class_of_dev(hdev, skb);
2404 break;
2405
2406 case HCI_OP_WRITE_CLASS_OF_DEV:
2407 hci_cc_write_class_of_dev(hdev, skb);
2408 break;
2409
2410 case HCI_OP_READ_VOICE_SETTING:
2411 hci_cc_read_voice_setting(hdev, skb);
2412 break;
2413
2414 case HCI_OP_WRITE_VOICE_SETTING:
2415 hci_cc_write_voice_setting(hdev, skb);
2416 break;
2417
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002418 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2419 hci_cc_read_num_supported_iac(hdev, skb);
2420 break;
2421
Marcel Holtmann333140b2008-07-14 20:13:48 +02002422 case HCI_OP_WRITE_SSP_MODE:
2423 hci_cc_write_ssp_mode(hdev, skb);
2424 break;
2425
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08002426 case HCI_OP_WRITE_SC_SUPPORT:
2427 hci_cc_write_sc_support(hdev, skb);
2428 break;
2429
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002430 case HCI_OP_READ_LOCAL_VERSION:
2431 hci_cc_read_local_version(hdev, skb);
2432 break;
2433
2434 case HCI_OP_READ_LOCAL_COMMANDS:
2435 hci_cc_read_local_commands(hdev, skb);
2436 break;
2437
2438 case HCI_OP_READ_LOCAL_FEATURES:
2439 hci_cc_read_local_features(hdev, skb);
2440 break;
2441
Andre Guedes971e3a42011-06-30 19:20:52 -03002442 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2443 hci_cc_read_local_ext_features(hdev, skb);
2444 break;
2445
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002446 case HCI_OP_READ_BUFFER_SIZE:
2447 hci_cc_read_buffer_size(hdev, skb);
2448 break;
2449
2450 case HCI_OP_READ_BD_ADDR:
2451 hci_cc_read_bd_addr(hdev, skb);
2452 break;
2453
Johan Hedbergf332ec62013-03-15 17:07:11 -05002454 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2455 hci_cc_read_page_scan_activity(hdev, skb);
2456 break;
2457
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002458 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2459 hci_cc_write_page_scan_activity(hdev, skb);
2460 break;
2461
Johan Hedbergf332ec62013-03-15 17:07:11 -05002462 case HCI_OP_READ_PAGE_SCAN_TYPE:
2463 hci_cc_read_page_scan_type(hdev, skb);
2464 break;
2465
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002466 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2467 hci_cc_write_page_scan_type(hdev, skb);
2468 break;
2469
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002470 case HCI_OP_READ_DATA_BLOCK_SIZE:
2471 hci_cc_read_data_block_size(hdev, skb);
2472 break;
2473
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002474 case HCI_OP_READ_FLOW_CONTROL_MODE:
2475 hci_cc_read_flow_control_mode(hdev, skb);
2476 break;
2477
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002478 case HCI_OP_READ_LOCAL_AMP_INFO:
2479 hci_cc_read_local_amp_info(hdev, skb);
2480 break;
2481
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002482 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2483 hci_cc_read_local_amp_assoc(hdev, skb);
2484 break;
2485
Johan Hedbergd5859e22011-01-25 01:19:58 +02002486 case HCI_OP_READ_INQ_RSP_TX_POWER:
2487 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2488 break;
2489
Johan Hedberg980e1a52011-01-22 06:10:07 +02002490 case HCI_OP_PIN_CODE_REPLY:
2491 hci_cc_pin_code_reply(hdev, skb);
2492 break;
2493
2494 case HCI_OP_PIN_CODE_NEG_REPLY:
2495 hci_cc_pin_code_neg_reply(hdev, skb);
2496 break;
2497
Szymon Jancc35938b2011-03-22 13:12:21 +01002498 case HCI_OP_READ_LOCAL_OOB_DATA:
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08002499 hci_cc_read_local_oob_data(hdev, skb);
2500 break;
2501
2502 case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
2503 hci_cc_read_local_oob_ext_data(hdev, skb);
Szymon Jancc35938b2011-03-22 13:12:21 +01002504 break;
2505
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002506 case HCI_OP_LE_READ_BUFFER_SIZE:
2507 hci_cc_le_read_buffer_size(hdev, skb);
2508 break;
2509
Johan Hedberg60e77322013-01-22 14:01:59 +02002510 case HCI_OP_LE_READ_LOCAL_FEATURES:
2511 hci_cc_le_read_local_features(hdev, skb);
2512 break;
2513
Johan Hedberg8fa19092012-10-19 20:57:49 +03002514 case HCI_OP_LE_READ_ADV_TX_POWER:
2515 hci_cc_le_read_adv_tx_power(hdev, skb);
2516 break;
2517
Johan Hedberga5c29682011-02-19 12:05:57 -03002518 case HCI_OP_USER_CONFIRM_REPLY:
2519 hci_cc_user_confirm_reply(hdev, skb);
2520 break;
2521
2522 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2523 hci_cc_user_confirm_neg_reply(hdev, skb);
2524 break;
2525
Brian Gix1143d452011-11-23 08:28:34 -08002526 case HCI_OP_USER_PASSKEY_REPLY:
2527 hci_cc_user_passkey_reply(hdev, skb);
2528 break;
2529
2530 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2531 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002532 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002533
Marcel Holtmann7a4cd512014-02-19 19:52:13 -08002534 case HCI_OP_LE_SET_RANDOM_ADDR:
2535 hci_cc_le_set_random_addr(hdev, skb);
2536 break;
2537
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002538 case HCI_OP_LE_SET_ADV_ENABLE:
2539 hci_cc_le_set_adv_enable(hdev, skb);
2540 break;
2541
Marcel Holtmann533553f2014-03-21 12:18:10 -07002542 case HCI_OP_LE_SET_SCAN_PARAM:
2543 hci_cc_le_set_scan_param(hdev, skb);
2544 break;
2545
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002546 case HCI_OP_LE_SET_SCAN_ENABLE:
2547 hci_cc_le_set_scan_enable(hdev, skb);
2548 break;
2549
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002550 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2551 hci_cc_le_read_white_list_size(hdev, skb);
2552 break;
2553
Marcel Holtmann0f36b582014-02-27 20:37:31 -08002554 case HCI_OP_LE_CLEAR_WHITE_LIST:
2555 hci_cc_le_clear_white_list(hdev, skb);
2556 break;
2557
2558 case HCI_OP_LE_ADD_TO_WHITE_LIST:
2559 hci_cc_le_add_to_white_list(hdev, skb);
2560 break;
2561
2562 case HCI_OP_LE_DEL_FROM_WHITE_LIST:
2563 hci_cc_le_del_from_white_list(hdev, skb);
2564 break;
2565
Johan Hedberg9b008c02013-01-22 14:02:01 +02002566 case HCI_OP_LE_READ_SUPPORTED_STATES:
2567 hci_cc_le_read_supported_states(hdev, skb);
2568 break;
2569
Andre Guedesf9b49302011-06-30 19:20:53 -03002570 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2571 hci_cc_write_le_host_supported(hdev, skb);
2572 break;
2573
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02002574 case HCI_OP_LE_SET_ADV_PARAM:
2575 hci_cc_set_adv_param(hdev, skb);
2576 break;
2577
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002578 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2579 hci_cc_write_remote_amp_assoc(hdev, skb);
2580 break;
2581
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002582 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002583 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002584 break;
2585 }
2586
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002587 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002588 del_timer(&hdev->cmd_timer);
2589
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002590 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002591
Szymon Jancdbccd792012-12-11 08:51:19 +01002592 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002593 atomic_set(&hdev->cmd_cnt, 1);
2594 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002595 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002596 }
2597}
2598
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002599static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002600{
2601 struct hci_ev_cmd_status *ev = (void *) skb->data;
2602 __u16 opcode;
2603
2604 skb_pull(skb, sizeof(*ev));
2605
2606 opcode = __le16_to_cpu(ev->opcode);
2607
2608 switch (opcode) {
2609 case HCI_OP_INQUIRY:
2610 hci_cs_inquiry(hdev, ev->status);
2611 break;
2612
2613 case HCI_OP_CREATE_CONN:
2614 hci_cs_create_conn(hdev, ev->status);
2615 break;
2616
2617 case HCI_OP_ADD_SCO:
2618 hci_cs_add_sco(hdev, ev->status);
2619 break;
2620
Marcel Holtmannf8558552008-07-14 20:13:49 +02002621 case HCI_OP_AUTH_REQUESTED:
2622 hci_cs_auth_requested(hdev, ev->status);
2623 break;
2624
2625 case HCI_OP_SET_CONN_ENCRYPT:
2626 hci_cs_set_conn_encrypt(hdev, ev->status);
2627 break;
2628
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002629 case HCI_OP_REMOTE_NAME_REQ:
2630 hci_cs_remote_name_req(hdev, ev->status);
2631 break;
2632
Marcel Holtmann769be972008-07-14 20:13:49 +02002633 case HCI_OP_READ_REMOTE_FEATURES:
2634 hci_cs_read_remote_features(hdev, ev->status);
2635 break;
2636
2637 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2638 hci_cs_read_remote_ext_features(hdev, ev->status);
2639 break;
2640
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002641 case HCI_OP_SETUP_SYNC_CONN:
2642 hci_cs_setup_sync_conn(hdev, ev->status);
2643 break;
2644
2645 case HCI_OP_SNIFF_MODE:
2646 hci_cs_sniff_mode(hdev, ev->status);
2647 break;
2648
2649 case HCI_OP_EXIT_SNIFF_MODE:
2650 hci_cs_exit_sniff_mode(hdev, ev->status);
2651 break;
2652
Johan Hedberg8962ee72011-01-20 12:40:27 +02002653 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002654 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002655 break;
2656
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002657 case HCI_OP_CREATE_PHY_LINK:
2658 hci_cs_create_phylink(hdev, ev->status);
2659 break;
2660
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002661 case HCI_OP_ACCEPT_PHY_LINK:
2662 hci_cs_accept_phylink(hdev, ev->status);
2663 break;
2664
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02002665 case HCI_OP_LE_CREATE_CONN:
2666 hci_cs_le_create_conn(hdev, ev->status);
2667 break;
2668
Johan Hedberg81d0c8a2014-03-24 14:39:04 +02002669 case HCI_OP_LE_START_ENC:
2670 hci_cs_le_start_enc(hdev, ev->status);
2671 break;
2672
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002673 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002674 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002675 break;
2676 }
2677
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002678 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002679 del_timer(&hdev->cmd_timer);
2680
Johan Hedberg02350a72013-04-03 21:50:29 +03002681 if (ev->status ||
2682 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2683 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002684
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002685 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002686 atomic_set(&hdev->cmd_cnt, 1);
2687 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002688 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002689 }
2690}
2691
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002692static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002693{
2694 struct hci_ev_role_change *ev = (void *) skb->data;
2695 struct hci_conn *conn;
2696
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002697 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002698
2699 hci_dev_lock(hdev);
2700
2701 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2702 if (conn) {
2703 if (!ev->status) {
2704 if (ev->role)
2705 conn->link_mode &= ~HCI_LM_MASTER;
2706 else
2707 conn->link_mode |= HCI_LM_MASTER;
2708 }
2709
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002710 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002711
2712 hci_role_switch_cfm(conn, ev->status, ev->role);
2713 }
2714
2715 hci_dev_unlock(hdev);
2716}
2717
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002718static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002720 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002721 int i;
2722
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002723 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2724 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2725 return;
2726 }
2727
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002728 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002729 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002730 BT_DBG("%s bad parameters", hdev->name);
2731 return;
2732 }
2733
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002734 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2735
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002736 for (i = 0; i < ev->num_hndl; i++) {
2737 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002738 struct hci_conn *conn;
2739 __u16 handle, count;
2740
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002741 handle = __le16_to_cpu(info->handle);
2742 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002743
2744 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002745 if (!conn)
2746 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002747
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002748 conn->sent -= count;
2749
2750 switch (conn->type) {
2751 case ACL_LINK:
2752 hdev->acl_cnt += count;
2753 if (hdev->acl_cnt > hdev->acl_pkts)
2754 hdev->acl_cnt = hdev->acl_pkts;
2755 break;
2756
2757 case LE_LINK:
2758 if (hdev->le_pkts) {
2759 hdev->le_cnt += count;
2760 if (hdev->le_cnt > hdev->le_pkts)
2761 hdev->le_cnt = hdev->le_pkts;
2762 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002763 hdev->acl_cnt += count;
2764 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002765 hdev->acl_cnt = hdev->acl_pkts;
2766 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002767 break;
2768
2769 case SCO_LINK:
2770 hdev->sco_cnt += count;
2771 if (hdev->sco_cnt > hdev->sco_pkts)
2772 hdev->sco_cnt = hdev->sco_pkts;
2773 break;
2774
2775 default:
2776 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2777 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002778 }
2779 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002780
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002781 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002782}
2783
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002784static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2785 __u16 handle)
2786{
2787 struct hci_chan *chan;
2788
2789 switch (hdev->dev_type) {
2790 case HCI_BREDR:
2791 return hci_conn_hash_lookup_handle(hdev, handle);
2792 case HCI_AMP:
2793 chan = hci_chan_lookup_handle(hdev, handle);
2794 if (chan)
2795 return chan->conn;
2796 break;
2797 default:
2798 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2799 break;
2800 }
2801
2802 return NULL;
2803}
2804
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002805static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002806{
2807 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2808 int i;
2809
2810 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2811 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2812 return;
2813 }
2814
2815 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002816 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002817 BT_DBG("%s bad parameters", hdev->name);
2818 return;
2819 }
2820
2821 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002822 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002823
2824 for (i = 0; i < ev->num_hndl; i++) {
2825 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002826 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002827 __u16 handle, block_count;
2828
2829 handle = __le16_to_cpu(info->handle);
2830 block_count = __le16_to_cpu(info->blocks);
2831
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002832 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002833 if (!conn)
2834 continue;
2835
2836 conn->sent -= block_count;
2837
2838 switch (conn->type) {
2839 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002840 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002841 hdev->block_cnt += block_count;
2842 if (hdev->block_cnt > hdev->num_blocks)
2843 hdev->block_cnt = hdev->num_blocks;
2844 break;
2845
2846 default:
2847 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2848 break;
2849 }
2850 }
2851
2852 queue_work(hdev->workqueue, &hdev->tx_work);
2853}
2854
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002855static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002857 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002858 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002860 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002861
2862 hci_dev_lock(hdev);
2863
Marcel Holtmann04837f62006-07-03 10:02:33 +02002864 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2865 if (conn) {
2866 conn->mode = ev->mode;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002867
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002868 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2869 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002870 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002871 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002872 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002873 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002874 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002875
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002876 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002877 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002878 }
2879
2880 hci_dev_unlock(hdev);
2881}
2882
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002883static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002885 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2886 struct hci_conn *conn;
2887
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002888 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002889
2890 hci_dev_lock(hdev);
2891
2892 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002893 if (!conn)
2894 goto unlock;
2895
2896 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002897 hci_conn_hold(conn);
2898 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002899 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002900 }
2901
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002902 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002903 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002904 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002905 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002906 u8 secure;
2907
2908 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2909 secure = 1;
2910 else
2911 secure = 0;
2912
Johan Hedberg744cf192011-11-08 20:40:14 +02002913 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002914 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002915
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002916unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002917 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918}
2919
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002920static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002921{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002922 struct hci_ev_link_key_req *ev = (void *) skb->data;
2923 struct hci_cp_link_key_reply cp;
2924 struct hci_conn *conn;
2925 struct link_key *key;
2926
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002927 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002928
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002929 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002930 return;
2931
2932 hci_dev_lock(hdev);
2933
2934 key = hci_find_link_key(hdev, &ev->bdaddr);
2935 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002936 BT_DBG("%s link key not found for %pMR", hdev->name,
2937 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002938 goto not_found;
2939 }
2940
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002941 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2942 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002943
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002944 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002945 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002946 BT_DBG("%s ignoring debug key", hdev->name);
2947 goto not_found;
2948 }
2949
2950 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002951 if (conn) {
Marcel Holtmann66138ce2014-01-10 02:07:20 -08002952 if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
2953 key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002954 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002955 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2956 goto not_found;
2957 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002958
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002959 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002960 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002961 BT_DBG("%s ignoring key unauthenticated for high security",
2962 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002963 goto not_found;
2964 }
2965
2966 conn->key_type = key->type;
2967 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002968 }
2969
2970 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002971 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002972
2973 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2974
2975 hci_dev_unlock(hdev);
2976
2977 return;
2978
2979not_found:
2980 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2981 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002982}
2983
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002984static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002986 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2987 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002988 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002989
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002990 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002991
2992 hci_dev_lock(hdev);
2993
2994 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2995 if (conn) {
2996 hci_conn_hold(conn);
2997 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002998 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002999
3000 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
3001 conn->key_type = ev->key_type;
3002
David Herrmann76a68ba2013-04-06 20:28:37 +02003003 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003004 }
3005
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03003006 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07003007 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003008 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02003009
Marcel Holtmann052b30b2009-04-26 20:01:22 +02003010 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003011}
3012
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003013static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02003014{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003015 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02003016 struct hci_conn *conn;
3017
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003018 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02003019
3020 hci_dev_lock(hdev);
3021
3022 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003023 if (conn && !ev->status) {
3024 struct inquiry_entry *ie;
3025
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003026 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3027 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003028 ie->data.clock_offset = ev->clock_offset;
3029 ie->timestamp = jiffies;
3030 }
3031 }
3032
3033 hci_dev_unlock(hdev);
3034}
3035
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003036static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02003037{
3038 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
3039 struct hci_conn *conn;
3040
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003041 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02003042
3043 hci_dev_lock(hdev);
3044
3045 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3046 if (conn && !ev->status)
3047 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
3048
3049 hci_dev_unlock(hdev);
3050}
3051
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003052static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003053{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003054 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003055 struct inquiry_entry *ie;
3056
3057 BT_DBG("%s", hdev->name);
3058
3059 hci_dev_lock(hdev);
3060
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003061 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3062 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003063 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
3064 ie->timestamp = jiffies;
3065 }
3066
3067 hci_dev_unlock(hdev);
3068}
3069
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003070static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
3071 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003072{
3073 struct inquiry_data data;
3074 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003075 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003076
3077 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3078
3079 if (!num_rsp)
3080 return;
3081
Andre Guedes1519cc12012-03-21 00:03:38 -03003082 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3083 return;
3084
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003085 hci_dev_lock(hdev);
3086
3087 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01003088 struct inquiry_info_with_rssi_and_pscan_mode *info;
3089 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003090
Johan Hedberge17acd42011-03-30 23:57:16 +03003091 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003092 bacpy(&data.bdaddr, &info->bdaddr);
3093 data.pscan_rep_mode = info->pscan_rep_mode;
3094 data.pscan_period_mode = info->pscan_period_mode;
3095 data.pscan_mode = info->pscan_mode;
3096 memcpy(data.dev_class, info->dev_class, 3);
3097 data.clock_offset = info->clock_offset;
3098 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003099 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003100
3101 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003102 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003103 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003104 info->dev_class, info->rssi,
3105 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003106 }
3107 } else {
3108 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
3109
Johan Hedberge17acd42011-03-30 23:57:16 +03003110 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003111 bacpy(&data.bdaddr, &info->bdaddr);
3112 data.pscan_rep_mode = info->pscan_rep_mode;
3113 data.pscan_period_mode = info->pscan_period_mode;
3114 data.pscan_mode = 0x00;
3115 memcpy(data.dev_class, info->dev_class, 3);
3116 data.clock_offset = info->clock_offset;
3117 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003118 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003119 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003120 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003121 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003122 info->dev_class, info->rssi,
3123 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003124 }
3125 }
3126
3127 hci_dev_unlock(hdev);
3128}
3129
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003130static void hci_remote_ext_features_evt(struct hci_dev *hdev,
3131 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003132{
Marcel Holtmann41a96212008-07-14 20:13:48 +02003133 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
3134 struct hci_conn *conn;
3135
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003136 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003137
Marcel Holtmann41a96212008-07-14 20:13:48 +02003138 hci_dev_lock(hdev);
3139
3140 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02003141 if (!conn)
3142 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003143
Johan Hedbergcad718e2013-04-17 15:00:51 +03003144 if (ev->page < HCI_MAX_PAGES)
3145 memcpy(conn->features[ev->page], ev->features, 8);
3146
Johan Hedbergccd556f2010-11-10 17:11:51 +02003147 if (!ev->status && ev->page == 0x01) {
3148 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003149
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003150 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3151 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003152 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02003153
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05303154 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02003155 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05303156 } else {
3157 /* It is mandatory by the Bluetooth specification that
3158 * Extended Inquiry Results are only used when Secure
3159 * Simple Pairing is enabled, but some devices violate
3160 * this.
3161 *
3162 * To make these devices work, the internal SSP
3163 * enabled flag needs to be cleared if the remote host
3164 * features do not indicate SSP support */
3165 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
3166 }
Marcel Holtmanneb9a8f32014-01-15 22:37:38 -08003167
3168 if (ev->features[0] & LMP_HOST_SC)
3169 set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003170 }
3171
Johan Hedbergccd556f2010-11-10 17:11:51 +02003172 if (conn->state != BT_CONFIG)
3173 goto unlock;
3174
Johan Hedberg671267b2012-05-12 16:11:50 -03003175 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02003176 struct hci_cp_remote_name_req cp;
3177 memset(&cp, 0, sizeof(cp));
3178 bacpy(&cp.bdaddr, &conn->dst);
3179 cp.pscan_rep_mode = 0x02;
3180 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02003181 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3182 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003183 conn->dst_type, 0, NULL, 0,
3184 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02003185
Johan Hedberg127178d2010-11-18 22:22:29 +02003186 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02003187 conn->state = BT_CONNECTED;
3188 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003189 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02003190 }
3191
3192unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02003193 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003194}
3195
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003196static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
3197 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003198{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003199 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
3200 struct hci_conn *conn;
3201
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003202 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003203
3204 hci_dev_lock(hdev);
3205
3206 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02003207 if (!conn) {
3208 if (ev->link_type == ESCO_LINK)
3209 goto unlock;
3210
3211 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
3212 if (!conn)
3213 goto unlock;
3214
3215 conn->type = SCO_LINK;
3216 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003217
Marcel Holtmann732547f2009-04-19 19:14:14 +02003218 switch (ev->status) {
3219 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003220 conn->handle = __le16_to_cpu(ev->handle);
3221 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02003222
3223 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02003224 break;
3225
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02003226 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05003227 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003228 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08003229 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003230 case 0x1f: /* Unspecified error */
Andrew Earl27539bc2014-03-10 10:31:04 +00003231 case 0x20: /* Unsupported LMP Parameter value */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003232 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02003233 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
3234 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003235 if (hci_setup_sync(conn, conn->link->handle))
3236 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003237 }
3238 /* fall through */
3239
3240 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003241 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003242 break;
3243 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003244
3245 hci_proto_connect_cfm(conn, ev->status);
3246 if (ev->status)
3247 hci_conn_del(conn);
3248
3249unlock:
3250 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003251}
3252
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07003253static inline size_t eir_get_length(u8 *eir, size_t eir_len)
3254{
3255 size_t parsed = 0;
3256
3257 while (parsed < eir_len) {
3258 u8 field_len = eir[0];
3259
3260 if (field_len == 0)
3261 return parsed;
3262
3263 parsed += field_len + 1;
3264 eir += field_len + 1;
3265 }
3266
3267 return eir_len;
3268}
3269
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003270static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3271 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003272{
3273 struct inquiry_data data;
3274 struct extended_inquiry_info *info = (void *) (skb->data + 1);
3275 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303276 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003277
3278 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3279
3280 if (!num_rsp)
3281 return;
3282
Andre Guedes1519cc12012-03-21 00:03:38 -03003283 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3284 return;
3285
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003286 hci_dev_lock(hdev);
3287
Johan Hedberge17acd42011-03-30 23:57:16 +03003288 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003289 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003290
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003291 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003292 data.pscan_rep_mode = info->pscan_rep_mode;
3293 data.pscan_period_mode = info->pscan_period_mode;
3294 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003295 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003296 data.clock_offset = info->clock_offset;
3297 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003298 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003299
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003300 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003301 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003302 sizeof(info->data),
3303 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003304 else
3305 name_known = true;
3306
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003307 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003308 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303309 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003310 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003311 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303312 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003313 }
3314
3315 hci_dev_unlock(hdev);
3316}
3317
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003318static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3319 struct sk_buff *skb)
3320{
3321 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3322 struct hci_conn *conn;
3323
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003324 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003325 __le16_to_cpu(ev->handle));
3326
3327 hci_dev_lock(hdev);
3328
3329 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3330 if (!conn)
3331 goto unlock;
3332
3333 if (!ev->status)
3334 conn->sec_level = conn->pending_sec_level;
3335
3336 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3337
3338 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003339 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003340 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003341 goto unlock;
3342 }
3343
3344 if (conn->state == BT_CONFIG) {
3345 if (!ev->status)
3346 conn->state = BT_CONNECTED;
3347
3348 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003349 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003350 } else {
3351 hci_auth_cfm(conn, ev->status);
3352
3353 hci_conn_hold(conn);
3354 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003355 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003356 }
3357
3358unlock:
3359 hci_dev_unlock(hdev);
3360}
3361
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003362static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003363{
3364 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003365 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3366 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003367 /* If both remote and local IO capabilities allow MITM
3368 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003369 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3370 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3371 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003372 else
Mikel Astizacabae92013-06-28 10:56:28 +02003373 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003374 }
3375
3376 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003377 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3378 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003379 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003380
3381 return conn->auth_type;
3382}
3383
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003384static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003385{
3386 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3387 struct hci_conn *conn;
3388
3389 BT_DBG("%s", hdev->name);
3390
3391 hci_dev_lock(hdev);
3392
3393 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003394 if (!conn)
3395 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003396
Johan Hedberg03b555e2011-01-04 15:40:05 +02003397 hci_conn_hold(conn);
3398
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003399 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003400 goto unlock;
3401
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003402 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003403 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003404 struct hci_cp_io_capability_reply cp;
3405
3406 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303407 /* Change the IO capability from KeyboardDisplay
3408 * to DisplayYesNo as it is not supported by BT spec. */
3409 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003410 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003411 conn->auth_type = hci_get_auth_req(conn);
3412 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003413
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003414 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3415 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003416 cp.oob_data = 0x01;
3417 else
3418 cp.oob_data = 0x00;
3419
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003420 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003421 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003422 } else {
3423 struct hci_cp_io_capability_neg_reply cp;
3424
3425 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003426 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003427
3428 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003429 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003430 }
3431
3432unlock:
3433 hci_dev_unlock(hdev);
3434}
3435
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003436static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003437{
3438 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3439 struct hci_conn *conn;
3440
3441 BT_DBG("%s", hdev->name);
3442
3443 hci_dev_lock(hdev);
3444
3445 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3446 if (!conn)
3447 goto unlock;
3448
Johan Hedberg03b555e2011-01-04 15:40:05 +02003449 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003450 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003451 if (ev->oob_data)
3452 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003453
3454unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003455 hci_dev_unlock(hdev);
3456}
3457
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003458static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3459 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003460{
3461 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003462 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003463 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003464
3465 BT_DBG("%s", hdev->name);
3466
3467 hci_dev_lock(hdev);
3468
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003469 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003470 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003471
Johan Hedberg7a828902011-04-28 11:28:53 -07003472 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3473 if (!conn)
3474 goto unlock;
3475
3476 loc_mitm = (conn->auth_type & 0x01);
3477 rem_mitm = (conn->remote_auth & 0x01);
3478
3479 /* If we require MITM but the remote device can't provide that
3480 * (it has NoInputNoOutput) then reject the confirmation
3481 * request. The only exception is when we're dedicated bonding
3482 * initiators (connect_cfm_cb set) since then we always have the MITM
3483 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003484 if (!conn->connect_cfm_cb && loc_mitm &&
3485 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003486 BT_DBG("Rejecting request: remote device can't provide MITM");
3487 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003488 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003489 goto unlock;
3490 }
3491
3492 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003493 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3494 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003495
3496 /* If we're not the initiators request authorization to
3497 * proceed from user space (mgmt_user_confirm with
3498 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003499 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003500 BT_DBG("Confirming auto-accept as acceptor");
3501 confirm_hint = 1;
3502 goto confirm;
3503 }
3504
Johan Hedberg9f616562011-04-28 11:28:54 -07003505 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003506 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003507
3508 if (hdev->auto_accept_delay > 0) {
3509 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
Johan Hedberg7bc18d92013-10-16 18:11:39 +03003510 queue_delayed_work(conn->hdev->workqueue,
3511 &conn->auto_accept_work, delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003512 goto unlock;
3513 }
3514
Johan Hedberg7a828902011-04-28 11:28:53 -07003515 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003516 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003517 goto unlock;
3518 }
3519
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003520confirm:
Johan Hedberg39adbff2014-03-20 08:18:14 +02003521 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0,
3522 le32_to_cpu(ev->passkey), confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003523
3524unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003525 hci_dev_unlock(hdev);
3526}
3527
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003528static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3529 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003530{
3531 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3532
3533 BT_DBG("%s", hdev->name);
3534
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003535 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003536 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003537}
3538
Johan Hedberg92a25252012-09-06 18:39:26 +03003539static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3540 struct sk_buff *skb)
3541{
3542 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3543 struct hci_conn *conn;
3544
3545 BT_DBG("%s", hdev->name);
3546
3547 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3548 if (!conn)
3549 return;
3550
3551 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3552 conn->passkey_entered = 0;
3553
3554 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3555 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3556 conn->dst_type, conn->passkey_notify,
3557 conn->passkey_entered);
3558}
3559
3560static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3561{
3562 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3563 struct hci_conn *conn;
3564
3565 BT_DBG("%s", hdev->name);
3566
3567 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3568 if (!conn)
3569 return;
3570
3571 switch (ev->type) {
3572 case HCI_KEYPRESS_STARTED:
3573 conn->passkey_entered = 0;
3574 return;
3575
3576 case HCI_KEYPRESS_ENTERED:
3577 conn->passkey_entered++;
3578 break;
3579
3580 case HCI_KEYPRESS_ERASED:
3581 conn->passkey_entered--;
3582 break;
3583
3584 case HCI_KEYPRESS_CLEARED:
3585 conn->passkey_entered = 0;
3586 break;
3587
3588 case HCI_KEYPRESS_COMPLETED:
3589 return;
3590 }
3591
3592 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3593 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3594 conn->dst_type, conn->passkey_notify,
3595 conn->passkey_entered);
3596}
3597
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003598static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3599 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003600{
3601 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3602 struct hci_conn *conn;
3603
3604 BT_DBG("%s", hdev->name);
3605
3606 hci_dev_lock(hdev);
3607
3608 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003609 if (!conn)
3610 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003611
Johan Hedberg2a611692011-02-19 12:06:00 -03003612 /* To avoid duplicate auth_failed events to user space we check
3613 * the HCI_CONN_AUTH_PEND flag which will be set if we
3614 * initiated the authentication. A traditional auth_complete
3615 * event gets always produced as initiator and is also mapped to
3616 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003617 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003618 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003619 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003620
David Herrmann76a68ba2013-04-06 20:28:37 +02003621 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003622
3623unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003624 hci_dev_unlock(hdev);
3625}
3626
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003627static void hci_remote_host_features_evt(struct hci_dev *hdev,
3628 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003629{
3630 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3631 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003632 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003633
3634 BT_DBG("%s", hdev->name);
3635
3636 hci_dev_lock(hdev);
3637
Johan Hedbergcad718e2013-04-17 15:00:51 +03003638 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3639 if (conn)
3640 memcpy(conn->features[1], ev->features, 8);
3641
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003642 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3643 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003644 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003645
3646 hci_dev_unlock(hdev);
3647}
3648
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003649static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3650 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003651{
3652 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3653 struct oob_data *data;
3654
3655 BT_DBG("%s", hdev->name);
3656
3657 hci_dev_lock(hdev);
3658
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003659 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003660 goto unlock;
3661
Szymon Janc2763eda2011-03-22 13:12:22 +01003662 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3663 if (data) {
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003664 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
3665 struct hci_cp_remote_oob_ext_data_reply cp;
Szymon Janc2763eda2011-03-22 13:12:22 +01003666
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003667 bacpy(&cp.bdaddr, &ev->bdaddr);
3668 memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
3669 memcpy(cp.randomizer192, data->randomizer192,
3670 sizeof(cp.randomizer192));
3671 memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
3672 memcpy(cp.randomizer256, data->randomizer256,
3673 sizeof(cp.randomizer256));
Szymon Janc2763eda2011-03-22 13:12:22 +01003674
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003675 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
3676 sizeof(cp), &cp);
3677 } else {
3678 struct hci_cp_remote_oob_data_reply cp;
3679
3680 bacpy(&cp.bdaddr, &ev->bdaddr);
3681 memcpy(cp.hash, data->hash192, sizeof(cp.hash));
3682 memcpy(cp.randomizer, data->randomizer192,
3683 sizeof(cp.randomizer));
3684
3685 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
3686 sizeof(cp), &cp);
3687 }
Szymon Janc2763eda2011-03-22 13:12:22 +01003688 } else {
3689 struct hci_cp_remote_oob_data_neg_reply cp;
3690
3691 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003692 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
3693 sizeof(cp), &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003694 }
3695
Szymon Jance1ba1f12011-04-06 13:01:59 +02003696unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003697 hci_dev_unlock(hdev);
3698}
3699
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003700static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3701 struct sk_buff *skb)
3702{
3703 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3704 struct hci_conn *hcon, *bredr_hcon;
3705
3706 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3707 ev->status);
3708
3709 hci_dev_lock(hdev);
3710
3711 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3712 if (!hcon) {
3713 hci_dev_unlock(hdev);
3714 return;
3715 }
3716
3717 if (ev->status) {
3718 hci_conn_del(hcon);
3719 hci_dev_unlock(hdev);
3720 return;
3721 }
3722
3723 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3724
3725 hcon->state = BT_CONNECTED;
3726 bacpy(&hcon->dst, &bredr_hcon->dst);
3727
3728 hci_conn_hold(hcon);
3729 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003730 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003731
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003732 hci_conn_add_sysfs(hcon);
3733
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003734 amp_physical_cfm(bredr_hcon, hcon);
3735
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003736 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003737}
3738
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003739static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3740{
3741 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3742 struct hci_conn *hcon;
3743 struct hci_chan *hchan;
3744 struct amp_mgr *mgr;
3745
3746 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3747 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3748 ev->status);
3749
3750 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3751 if (!hcon)
3752 return;
3753
3754 /* Create AMP hchan */
3755 hchan = hci_chan_create(hcon);
3756 if (!hchan)
3757 return;
3758
3759 hchan->handle = le16_to_cpu(ev->handle);
3760
3761 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3762
3763 mgr = hcon->amp_mgr;
3764 if (mgr && mgr->bredr_chan) {
3765 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3766
3767 l2cap_chan_lock(bredr_chan);
3768
3769 bredr_chan->conn->mtu = hdev->block_mtu;
3770 l2cap_logical_cfm(bredr_chan, hchan, 0);
3771 hci_conn_hold(hcon);
3772
3773 l2cap_chan_unlock(bredr_chan);
3774 }
3775}
3776
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003777static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3778 struct sk_buff *skb)
3779{
3780 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3781 struct hci_chan *hchan;
3782
3783 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3784 le16_to_cpu(ev->handle), ev->status);
3785
3786 if (ev->status)
3787 return;
3788
3789 hci_dev_lock(hdev);
3790
3791 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3792 if (!hchan)
3793 goto unlock;
3794
3795 amp_destroy_logical_link(hchan, ev->reason);
3796
3797unlock:
3798 hci_dev_unlock(hdev);
3799}
3800
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003801static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3802 struct sk_buff *skb)
3803{
3804 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3805 struct hci_conn *hcon;
3806
3807 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3808
3809 if (ev->status)
3810 return;
3811
3812 hci_dev_lock(hdev);
3813
3814 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3815 if (hcon) {
3816 hcon->state = BT_CLOSED;
3817 hci_conn_del(hcon);
3818 }
3819
3820 hci_dev_unlock(hdev);
3821}
3822
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003823static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003824{
3825 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3826 struct hci_conn *conn;
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003827 struct smp_irk *irk;
Ville Tervofcd89c02011-02-10 22:38:47 -03003828
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003829 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003830
3831 hci_dev_lock(hdev);
3832
Andre Guedesb47a09b2012-07-27 15:10:15 -03003833 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003834 if (!conn) {
3835 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3836 if (!conn) {
3837 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003838 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003839 }
Andre Guedes29b79882011-05-31 14:20:54 -03003840
3841 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003842
Marcel Holtmann880be4e2013-10-13 07:25:18 -07003843 /* The advertising parameters for own address type
3844 * define which source address and source address
3845 * type this connections has.
3846 */
3847 if (bacmp(&conn->src, BDADDR_ANY)) {
3848 conn->src_type = ADDR_LE_DEV_PUBLIC;
3849 } else {
3850 bacpy(&conn->src, &hdev->static_addr);
3851 conn->src_type = ADDR_LE_DEV_RANDOM;
3852 }
3853
Andre Guedesb9b343d2012-07-27 15:10:11 -03003854 if (ev->role == LE_CONN_ROLE_MASTER) {
3855 conn->out = true;
3856 conn->link_mode |= HCI_LM_MASTER;
3857 }
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02003858
3859 /* If we didn't have a hci_conn object previously
3860 * but we're in master role this must be something
3861 * initiated using a white list. Since white list based
3862 * connections are not "first class citizens" we don't
3863 * have full tracking of them. Therefore, we go ahead
3864 * with a "best effort" approach of determining the
3865 * initiator address based on the HCI_PRIVACY flag.
3866 */
3867 if (conn->out) {
3868 conn->resp_addr_type = ev->bdaddr_type;
3869 bacpy(&conn->resp_addr, &ev->bdaddr);
3870 if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
3871 conn->init_addr_type = ADDR_LE_DEV_RANDOM;
3872 bacpy(&conn->init_addr, &hdev->rpa);
3873 } else {
3874 hci_copy_identity_address(hdev,
3875 &conn->init_addr,
3876 &conn->init_addr_type);
3877 }
3878 } else {
3879 /* Set the responder (our side) address type based on
3880 * the advertising address type.
3881 */
3882 conn->resp_addr_type = hdev->adv_addr_type;
3883 if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM)
3884 bacpy(&conn->resp_addr, &hdev->random_addr);
3885 else
3886 bacpy(&conn->resp_addr, &hdev->bdaddr);
3887
3888 conn->init_addr_type = ev->bdaddr_type;
3889 bacpy(&conn->init_addr, &ev->bdaddr);
3890 }
Johan Hedberg9489eca2014-02-28 17:45:46 +02003891 } else {
3892 cancel_delayed_work(&conn->le_conn_timeout);
Ville Tervob62f3282011-02-10 22:38:50 -03003893 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003894
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003895 /* Ensure that the hci_conn contains the identity address type
3896 * regardless of which address the connection was made with.
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003897 */
Johan Hedberga1f4c312014-02-27 14:05:41 +02003898 hci_copy_identity_address(hdev, &conn->src, &conn->src_type);
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003899
Marcel Holtmannedb4b462014-02-18 15:13:43 -08003900 /* Lookup the identity address from the stored connection
3901 * address and address type.
3902 *
3903 * When establishing connections to an identity address, the
3904 * connection procedure will store the resolvable random
3905 * address first. Now if it can be converted back into the
3906 * identity address, start using the identity address from
3907 * now on.
3908 */
3909 irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003910 if (irk) {
3911 bacpy(&conn->dst, &irk->bdaddr);
3912 conn->dst_type = irk->addr_type;
3913 }
3914
Andre Guedescd17dec2012-07-27 15:10:16 -03003915 if (ev->status) {
Andre Guedes06c053f2014-02-26 20:21:41 -03003916 hci_le_conn_failed(conn, ev->status);
Andre Guedescd17dec2012-07-27 15:10:16 -03003917 goto unlock;
3918 }
3919
Johan Hedbergb644ba32012-01-17 21:48:47 +02003920 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Marcel Holtmann01fdb0f2014-02-18 14:22:19 -08003921 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003922 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003923
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003924 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003925 conn->handle = __le16_to_cpu(ev->handle);
3926 conn->state = BT_CONNECTED;
3927
Jukka Rissanen18722c22013-12-11 17:05:37 +02003928 if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
3929 set_bit(HCI_CONN_6LOWPAN, &conn->flags);
3930
Ville Tervofcd89c02011-02-10 22:38:47 -03003931 hci_conn_add_sysfs(conn);
3932
3933 hci_proto_connect_cfm(conn, ev->status);
3934
Andre Guedesa4790db2014-02-26 20:21:47 -03003935 hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type);
3936
Ville Tervofcd89c02011-02-10 22:38:47 -03003937unlock:
3938 hci_dev_unlock(hdev);
3939}
3940
Andre Guedesa4790db2014-02-26 20:21:47 -03003941/* This function requires the caller holds hdev->lock */
3942static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
3943 u8 addr_type)
3944{
3945 struct hci_conn *conn;
Andre Guedes5b906a82014-02-26 20:21:53 -03003946 struct smp_irk *irk;
3947
3948 /* If this is a resolvable address, we should resolve it and then
3949 * update address and address type variables.
3950 */
3951 irk = hci_get_irk(hdev, addr, addr_type);
3952 if (irk) {
3953 addr = &irk->bdaddr;
3954 addr_type = irk->addr_type;
3955 }
Andre Guedesa4790db2014-02-26 20:21:47 -03003956
3957 if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
3958 return;
3959
3960 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
3961 HCI_AT_NO_BONDING);
3962 if (!IS_ERR(conn))
3963 return;
3964
3965 switch (PTR_ERR(conn)) {
3966 case -EBUSY:
3967 /* If hci_connect() returns -EBUSY it means there is already
3968 * an LE connection attempt going on. Since controllers don't
3969 * support more than one connection attempt at the time, we
3970 * don't consider this an error case.
3971 */
3972 break;
3973 default:
3974 BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
3975 }
3976}
3977
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003978static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003979{
Andre Guedese95beb42011-09-26 20:48:35 -03003980 u8 num_reports = skb->data[0];
3981 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003982 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003983
Andre Guedesa4790db2014-02-26 20:21:47 -03003984 hci_dev_lock(hdev);
3985
Andre Guedese95beb42011-09-26 20:48:35 -03003986 while (num_reports--) {
3987 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003988
Andre Guedesa4790db2014-02-26 20:21:47 -03003989 if (ev->evt_type == LE_ADV_IND ||
3990 ev->evt_type == LE_ADV_DIRECT_IND)
3991 check_pending_le_conn(hdev, &ev->bdaddr,
3992 ev->bdaddr_type);
3993
Andre Guedes3c9e9192012-01-10 18:20:50 -03003994 rssi = ev->data[ev->length];
3995 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003996 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003997
Andre Guedese95beb42011-09-26 20:48:35 -03003998 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003999 }
Andre Guedesa4790db2014-02-26 20:21:47 -03004000
4001 hci_dev_unlock(hdev);
Andre Guedes9aa04c92011-05-26 16:23:51 -03004002}
4003
Gustavo Padovan6039aa732012-05-23 04:04:18 -03004004static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004005{
4006 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
4007 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004008 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004009 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03004010 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004011
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03004012 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004013
4014 hci_dev_lock(hdev);
4015
4016 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004017 if (conn == NULL)
4018 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004019
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08004020 ltk = hci_find_ltk(hdev, ev->ediv, ev->rand, conn->out);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004021 if (ltk == NULL)
4022 goto not_found;
4023
4024 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004025 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03004026
4027 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03004028 conn->pending_sec_level = BT_SECURITY_HIGH;
4029 else
4030 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004031
Andre Guedes89cbb4d2013-07-31 16:25:29 -03004032 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004033
4034 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
4035
Claudio Takahasi5981a882013-07-25 16:34:24 -03004036 /* Ref. Bluetooth Core SPEC pages 1975 and 2004. STK is a
4037 * temporary key used to encrypt a connection following
4038 * pairing. It is used during the Encrypted Session Setup to
4039 * distribute the keys. Later, security can be re-established
4040 * using a distributed LTK.
4041 */
4042 if (ltk->type == HCI_SMP_STK_SLAVE) {
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03004043 list_del(&ltk->list);
4044 kfree(ltk);
4045 }
4046
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004047 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03004048
4049 return;
4050
4051not_found:
4052 neg.handle = ev->handle;
4053 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
4054 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004055}
4056
Gustavo Padovan6039aa732012-05-23 04:04:18 -03004057static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03004058{
4059 struct hci_ev_le_meta *le_ev = (void *) skb->data;
4060
4061 skb_pull(skb, sizeof(*le_ev));
4062
4063 switch (le_ev->subevent) {
4064 case HCI_EV_LE_CONN_COMPLETE:
4065 hci_le_conn_complete_evt(hdev, skb);
4066 break;
4067
Andre Guedes9aa04c92011-05-26 16:23:51 -03004068 case HCI_EV_LE_ADVERTISING_REPORT:
4069 hci_le_adv_report_evt(hdev, skb);
4070 break;
4071
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03004072 case HCI_EV_LE_LTK_REQ:
4073 hci_le_ltk_request_evt(hdev, skb);
4074 break;
4075
Ville Tervofcd89c02011-02-10 22:38:47 -03004076 default:
4077 break;
4078 }
4079}
4080
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004081static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
4082{
4083 struct hci_ev_channel_selected *ev = (void *) skb->data;
4084 struct hci_conn *hcon;
4085
4086 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
4087
4088 skb_pull(skb, sizeof(*ev));
4089
4090 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
4091 if (!hcon)
4092 return;
4093
4094 amp_read_loc_assoc_final_data(hdev, hcon);
4095}
4096
Linus Torvalds1da177e2005-04-16 15:20:36 -07004097void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
4098{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004099 struct hci_event_hdr *hdr = (void *) skb->data;
4100 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004101
Johan Hedbergb6ddb632013-04-02 13:34:31 +03004102 hci_dev_lock(hdev);
4103
4104 /* Received events are (currently) only needed when a request is
4105 * ongoing so avoid unnecessary memory allocation.
4106 */
4107 if (hdev->req_status == HCI_REQ_PEND) {
4108 kfree_skb(hdev->recv_evt);
4109 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
4110 }
4111
4112 hci_dev_unlock(hdev);
4113
Linus Torvalds1da177e2005-04-16 15:20:36 -07004114 skb_pull(skb, HCI_EVENT_HDR_SIZE);
4115
Johan Hedberg02350a72013-04-03 21:50:29 +03004116 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02004117 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
4118 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03004119
4120 hci_req_cmd_complete(hdev, opcode, 0);
4121 }
4122
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004123 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004124 case HCI_EV_INQUIRY_COMPLETE:
4125 hci_inquiry_complete_evt(hdev, skb);
4126 break;
4127
4128 case HCI_EV_INQUIRY_RESULT:
4129 hci_inquiry_result_evt(hdev, skb);
4130 break;
4131
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004132 case HCI_EV_CONN_COMPLETE:
4133 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02004134 break;
4135
Linus Torvalds1da177e2005-04-16 15:20:36 -07004136 case HCI_EV_CONN_REQUEST:
4137 hci_conn_request_evt(hdev, skb);
4138 break;
4139
Linus Torvalds1da177e2005-04-16 15:20:36 -07004140 case HCI_EV_DISCONN_COMPLETE:
4141 hci_disconn_complete_evt(hdev, skb);
4142 break;
4143
Linus Torvalds1da177e2005-04-16 15:20:36 -07004144 case HCI_EV_AUTH_COMPLETE:
4145 hci_auth_complete_evt(hdev, skb);
4146 break;
4147
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004148 case HCI_EV_REMOTE_NAME:
4149 hci_remote_name_evt(hdev, skb);
4150 break;
4151
Linus Torvalds1da177e2005-04-16 15:20:36 -07004152 case HCI_EV_ENCRYPT_CHANGE:
4153 hci_encrypt_change_evt(hdev, skb);
4154 break;
4155
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004156 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
4157 hci_change_link_key_complete_evt(hdev, skb);
4158 break;
4159
4160 case HCI_EV_REMOTE_FEATURES:
4161 hci_remote_features_evt(hdev, skb);
4162 break;
4163
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004164 case HCI_EV_CMD_COMPLETE:
4165 hci_cmd_complete_evt(hdev, skb);
4166 break;
4167
4168 case HCI_EV_CMD_STATUS:
4169 hci_cmd_status_evt(hdev, skb);
4170 break;
4171
4172 case HCI_EV_ROLE_CHANGE:
4173 hci_role_change_evt(hdev, skb);
4174 break;
4175
4176 case HCI_EV_NUM_COMP_PKTS:
4177 hci_num_comp_pkts_evt(hdev, skb);
4178 break;
4179
4180 case HCI_EV_MODE_CHANGE:
4181 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004182 break;
4183
4184 case HCI_EV_PIN_CODE_REQ:
4185 hci_pin_code_request_evt(hdev, skb);
4186 break;
4187
4188 case HCI_EV_LINK_KEY_REQ:
4189 hci_link_key_request_evt(hdev, skb);
4190 break;
4191
4192 case HCI_EV_LINK_KEY_NOTIFY:
4193 hci_link_key_notify_evt(hdev, skb);
4194 break;
4195
4196 case HCI_EV_CLOCK_OFFSET:
4197 hci_clock_offset_evt(hdev, skb);
4198 break;
4199
Marcel Holtmanna8746412008-07-14 20:13:46 +02004200 case HCI_EV_PKT_TYPE_CHANGE:
4201 hci_pkt_type_change_evt(hdev, skb);
4202 break;
4203
Marcel Holtmann85a1e932005-08-09 20:28:02 -07004204 case HCI_EV_PSCAN_REP_MODE:
4205 hci_pscan_rep_mode_evt(hdev, skb);
4206 break;
4207
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004208 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
4209 hci_inquiry_result_with_rssi_evt(hdev, skb);
4210 break;
4211
4212 case HCI_EV_REMOTE_EXT_FEATURES:
4213 hci_remote_ext_features_evt(hdev, skb);
4214 break;
4215
4216 case HCI_EV_SYNC_CONN_COMPLETE:
4217 hci_sync_conn_complete_evt(hdev, skb);
4218 break;
4219
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004220 case HCI_EV_EXTENDED_INQUIRY_RESULT:
4221 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004222 break;
4223
Johan Hedberg1c2e0042012-06-08 23:31:13 +08004224 case HCI_EV_KEY_REFRESH_COMPLETE:
4225 hci_key_refresh_complete_evt(hdev, skb);
4226 break;
4227
Marcel Holtmann04936842008-07-14 20:13:48 +02004228 case HCI_EV_IO_CAPA_REQUEST:
4229 hci_io_capa_request_evt(hdev, skb);
4230 break;
4231
Johan Hedberg03b555e2011-01-04 15:40:05 +02004232 case HCI_EV_IO_CAPA_REPLY:
4233 hci_io_capa_reply_evt(hdev, skb);
4234 break;
4235
Johan Hedberga5c29682011-02-19 12:05:57 -03004236 case HCI_EV_USER_CONFIRM_REQUEST:
4237 hci_user_confirm_request_evt(hdev, skb);
4238 break;
4239
Brian Gix1143d452011-11-23 08:28:34 -08004240 case HCI_EV_USER_PASSKEY_REQUEST:
4241 hci_user_passkey_request_evt(hdev, skb);
4242 break;
4243
Johan Hedberg92a25252012-09-06 18:39:26 +03004244 case HCI_EV_USER_PASSKEY_NOTIFY:
4245 hci_user_passkey_notify_evt(hdev, skb);
4246 break;
4247
4248 case HCI_EV_KEYPRESS_NOTIFY:
4249 hci_keypress_notify_evt(hdev, skb);
4250 break;
4251
Marcel Holtmann04936842008-07-14 20:13:48 +02004252 case HCI_EV_SIMPLE_PAIR_COMPLETE:
4253 hci_simple_pair_complete_evt(hdev, skb);
4254 break;
4255
Marcel Holtmann41a96212008-07-14 20:13:48 +02004256 case HCI_EV_REMOTE_HOST_FEATURES:
4257 hci_remote_host_features_evt(hdev, skb);
4258 break;
4259
Ville Tervofcd89c02011-02-10 22:38:47 -03004260 case HCI_EV_LE_META:
4261 hci_le_meta_evt(hdev, skb);
4262 break;
4263
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004264 case HCI_EV_CHANNEL_SELECTED:
4265 hci_chan_selected_evt(hdev, skb);
4266 break;
4267
Szymon Janc2763eda2011-03-22 13:12:22 +01004268 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
4269 hci_remote_oob_data_request_evt(hdev, skb);
4270 break;
4271
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03004272 case HCI_EV_PHY_LINK_COMPLETE:
4273 hci_phy_link_complete_evt(hdev, skb);
4274 break;
4275
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004276 case HCI_EV_LOGICAL_LINK_COMPLETE:
4277 hci_loglink_complete_evt(hdev, skb);
4278 break;
4279
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02004280 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
4281 hci_disconn_loglink_complete_evt(hdev, skb);
4282 break;
4283
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02004284 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
4285 hci_disconn_phylink_complete_evt(hdev, skb);
4286 break;
4287
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02004288 case HCI_EV_NUM_COMP_BLOCKS:
4289 hci_num_comp_blocks_evt(hdev, skb);
4290 break;
4291
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004292 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03004293 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004294 break;
4295 }
4296
4297 kfree_skb(skb);
4298 hdev->stat.evt_rx++;
4299}