blob: 46da8b6f4368dc38f1d248d87f4908e168d59df4 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <asm/unaligned.h>
28
29#include <net/bluetooth/bluetooth.h>
30#include <net/bluetooth/hci_core.h>
Mikel Astizf0d6a0e2012-08-09 09:52:30 +020031#include <net/bluetooth/mgmt.h>
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070032
Marcel Holtmann70247282013-10-10 14:54:15 -070033#include "a2mp.h"
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070034#include "amp.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
Linus Torvalds1da177e2005-04-16 15:20:36 -070036/* Handle HCI Event packets */
37
Marcel Holtmanna9de9242007-10-20 13:33:56 +020038static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070039{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020040 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030042 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
Andre Guedes82f47852013-04-30 15:29:34 -030044 if (status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020045 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
Andre Guedes89352e72011-11-04 14:16:53 -030047 clear_bit(HCI_INQUIRY, &hdev->flags);
Andre Guedes3e13fa12013-03-27 20:04:56 -030048 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
49 wake_up_bit(&hdev->flags, HCI_INQUIRY);
Andre Guedes89352e72011-11-04 14:16:53 -030050
Marcel Holtmanna9de9242007-10-20 13:33:56 +020051 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070052}
53
Andre Guedes4d934832012-03-21 00:03:35 -030054static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
55{
56 __u8 status = *((__u8 *) skb->data);
57
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030058 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesae854a72012-03-21 00:03:36 -030059
60 if (status)
61 return;
62
63 set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
Andre Guedes4d934832012-03-21 00:03:35 -030064}
65
Marcel Holtmanna9de9242007-10-20 13:33:56 +020066static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020068 __u8 status = *((__u8 *) skb->data);
69
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030070 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020071
72 if (status)
73 return;
74
Andre Guedesae854a72012-03-21 00:03:36 -030075 clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
76
Marcel Holtmanna9de9242007-10-20 13:33:56 +020077 hci_conn_check_pending(hdev);
78}
79
Gustavo Padovan807deac2012-05-17 00:36:24 -030080static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
81 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020082{
83 BT_DBG("%s", hdev->name);
84}
85
86static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
87{
88 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030091 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
Marcel Holtmanna9de9242007-10-20 13:33:56 +020093 if (rp->status)
94 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
Marcel Holtmanna9de9242007-10-20 13:33:56 +020096 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Marcel Holtmanna9de9242007-10-20 13:33:56 +020098 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
99 if (conn) {
100 if (rp->role)
101 conn->link_mode &= ~HCI_LM_MASTER;
102 else
103 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200105
106 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107}
108
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200109static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
110{
111 struct hci_rp_read_link_policy *rp = (void *) skb->data;
112 struct hci_conn *conn;
113
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300114 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200115
116 if (rp->status)
117 return;
118
119 hci_dev_lock(hdev);
120
121 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
122 if (conn)
123 conn->link_policy = __le16_to_cpu(rp->policy);
124
125 hci_dev_unlock(hdev);
126}
127
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200128static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200130 struct hci_rp_write_link_policy *rp = (void *) skb->data;
131 struct hci_conn *conn;
132 void *sent;
133
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300134 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200135
136 if (rp->status)
137 return;
138
139 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
140 if (!sent)
141 return;
142
143 hci_dev_lock(hdev);
144
145 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200146 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700147 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200148
149 hci_dev_unlock(hdev);
150}
151
Gustavo Padovan807deac2012-05-17 00:36:24 -0300152static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
153 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200154{
155 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
156
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300157 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200158
159 if (rp->status)
160 return;
161
162 hdev->link_policy = __le16_to_cpu(rp->policy);
163}
164
Gustavo Padovan807deac2012-05-17 00:36:24 -0300165static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
166 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200167{
168 __u8 status = *((__u8 *) skb->data);
169 void *sent;
170
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300171 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200172
173 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
174 if (!sent)
175 return;
176
177 if (!status)
178 hdev->link_policy = get_unaligned_le16(sent);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200179}
180
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200181static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
182{
183 __u8 status = *((__u8 *) skb->data);
184
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300185 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200186
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300187 clear_bit(HCI_RESET, &hdev->flags);
188
Johan Hedberga297e972012-02-21 17:55:47 +0200189 /* Reset all non-persistent flags */
Johan Hedberg2cc6fb02013-03-15 17:06:57 -0500190 hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
Andre Guedes69775ff2012-02-23 16:50:05 +0200191
192 hdev->discovery.state = DISCOVERY_STOPPED;
Johan Hedbergbbaf4442012-11-08 01:22:59 +0100193 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
194 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100195
196 memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
197 hdev->adv_data_len = 0;
Marcel Holtmannf8e808b2013-10-16 00:16:47 -0700198
199 memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
200 hdev->scan_rsp_data_len = 0;
Marcel Holtmann06f5b772013-10-19 07:09:11 -0700201
202 hdev->ssp_debug_mode = 0;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200203}
204
205static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
206{
207 __u8 status = *((__u8 *) skb->data);
208 void *sent;
209
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300210 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200211
212 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
213 if (!sent)
214 return;
215
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200216 hci_dev_lock(hdev);
217
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200218 if (test_bit(HCI_MGMT, &hdev->dev_flags))
219 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200220 else if (!status)
221 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200222
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200223 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200224}
225
226static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
227{
228 struct hci_rp_read_local_name *rp = (void *) skb->data;
229
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300230 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200231
232 if (rp->status)
233 return;
234
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200235 if (test_bit(HCI_SETUP, &hdev->dev_flags))
236 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200237}
238
239static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
240{
241 __u8 status = *((__u8 *) skb->data);
242 void *sent;
243
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300244 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200245
246 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
247 if (!sent)
248 return;
249
250 if (!status) {
251 __u8 param = *((__u8 *) sent);
252
253 if (param == AUTH_ENABLED)
254 set_bit(HCI_AUTH, &hdev->flags);
255 else
256 clear_bit(HCI_AUTH, &hdev->flags);
257 }
258
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200259 if (test_bit(HCI_MGMT, &hdev->dev_flags))
260 mgmt_auth_enable_complete(hdev, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200261}
262
263static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
264{
265 __u8 status = *((__u8 *) skb->data);
266 void *sent;
267
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300268 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200269
270 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
271 if (!sent)
272 return;
273
274 if (!status) {
275 __u8 param = *((__u8 *) sent);
276
277 if (param)
278 set_bit(HCI_ENCRYPT, &hdev->flags);
279 else
280 clear_bit(HCI_ENCRYPT, &hdev->flags);
281 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200282}
283
284static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
285{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200286 __u8 param, status = *((__u8 *) skb->data);
287 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200288 void *sent;
289
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300290 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200291
292 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
293 if (!sent)
294 return;
295
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200296 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200297
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200298 hci_dev_lock(hdev);
299
Mikel Astizfa1bd912012-08-09 09:52:29 +0200300 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200301 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200302 hdev->discov_timeout = 0;
303 goto done;
304 }
305
Johan Hedberg0663ca22013-10-02 13:43:14 +0300306 /* We need to ensure that we set this back on if someone changed
307 * the scan mode through a raw HCI socket.
308 */
309 set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
310
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200311 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
312 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200313
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200314 if (param & SCAN_INQUIRY) {
315 set_bit(HCI_ISCAN, &hdev->flags);
316 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200317 mgmt_discoverable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200318 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200319 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200320
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200321 if (param & SCAN_PAGE) {
322 set_bit(HCI_PSCAN, &hdev->flags);
323 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200324 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200325 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200326 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200327
328done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200329 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200330}
331
332static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
333{
334 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
335
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300336 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200337
338 if (rp->status)
339 return;
340
341 memcpy(hdev->dev_class, rp->dev_class, 3);
342
343 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300344 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200345}
346
347static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
348{
349 __u8 status = *((__u8 *) skb->data);
350 void *sent;
351
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300352 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200353
354 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
355 if (!sent)
356 return;
357
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100358 hci_dev_lock(hdev);
359
360 if (status == 0)
361 memcpy(hdev->dev_class, sent, 3);
362
363 if (test_bit(HCI_MGMT, &hdev->dev_flags))
364 mgmt_set_class_of_dev_complete(hdev, sent, status);
365
366 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200367}
368
369static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
370{
371 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200373
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300374 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200375
376 if (rp->status)
377 return;
378
379 setting = __le16_to_cpu(rp->voice_setting);
380
Marcel Holtmannf383f272008-07-14 20:13:47 +0200381 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200382 return;
383
384 hdev->voice_setting = setting;
385
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300386 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200387
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200388 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200390}
391
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300392static void hci_cc_write_voice_setting(struct hci_dev *hdev,
393 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200394{
395 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200396 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 void *sent;
398
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300399 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
Marcel Holtmannf383f272008-07-14 20:13:47 +0200401 if (status)
402 return;
403
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200404 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
405 if (!sent)
406 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
Marcel Holtmannf383f272008-07-14 20:13:47 +0200408 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410 if (hdev->voice_setting == setting)
411 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
Marcel Holtmannf383f272008-07-14 20:13:47 +0200413 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300415 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200416
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200417 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200418 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419}
420
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -0700421static void hci_cc_read_num_supported_iac(struct hci_dev *hdev,
422 struct sk_buff *skb)
423{
424 struct hci_rp_read_num_supported_iac *rp = (void *) skb->data;
425
426 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
427
428 if (rp->status)
429 return;
430
431 hdev->num_iac = rp->num_iac;
432
433 BT_DBG("%s num iac %d", hdev->name, hdev->num_iac);
434}
435
Marcel Holtmann333140b2008-07-14 20:13:48 +0200436static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
437{
438 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300439 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200440
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300441 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200442
Marcel Holtmann333140b2008-07-14 20:13:48 +0200443 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
444 if (!sent)
445 return;
446
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300447 if (!status) {
448 if (sent->mode)
Johan Hedbergcad718e2013-04-17 15:00:51 +0300449 hdev->features[1][0] |= LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300450 else
Johan Hedbergcad718e2013-04-17 15:00:51 +0300451 hdev->features[1][0] &= ~LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300452 }
453
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200454 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300455 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200456 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300457 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200458 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
459 else
460 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
461 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200462}
463
Marcel Holtmanneac83dc2014-01-10 02:07:23 -0800464static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb)
465{
466 u8 status = *((u8 *) skb->data);
467 struct hci_cp_write_sc_support *sent;
468
469 BT_DBG("%s status 0x%2.2x", hdev->name, status);
470
471 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
472 if (!sent)
473 return;
474
475 if (!status) {
476 if (sent->support)
477 hdev->features[1][0] |= LMP_HOST_SC;
478 else
479 hdev->features[1][0] &= ~LMP_HOST_SC;
480 }
481
482 if (test_bit(HCI_MGMT, &hdev->dev_flags))
483 mgmt_sc_enable_complete(hdev, sent->support, status);
484 else if (!status) {
485 if (sent->support)
486 set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
487 else
488 clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
489 }
490}
491
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200492static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
493{
494 struct hci_rp_read_local_version *rp = (void *) skb->data;
495
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300496 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200497
498 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200499 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200500
Marcel Holtmann0d5551f2013-10-18 12:04:50 -0700501 if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
502 hdev->hci_ver = rp->hci_ver;
503 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
504 hdev->lmp_ver = rp->lmp_ver;
505 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
506 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
507 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200508}
509
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300510static void hci_cc_read_local_commands(struct hci_dev *hdev,
511 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200512{
513 struct hci_rp_read_local_commands *rp = (void *) skb->data;
514
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300515 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200516
Marcel Holtmann6a070e62013-10-31 04:54:33 -0700517 if (rp->status)
518 return;
519
520 if (test_bit(HCI_SETUP, &hdev->dev_flags))
Johan Hedberg2177bab2013-03-05 20:37:43 +0200521 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200522}
523
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300524static void hci_cc_read_local_features(struct hci_dev *hdev,
525 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200526{
527 struct hci_rp_read_local_features *rp = (void *) skb->data;
528
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300529 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200530
531 if (rp->status)
532 return;
533
534 memcpy(hdev->features, rp->features, 8);
535
536 /* Adjust default settings according to features
537 * supported by device. */
538
Johan Hedbergcad718e2013-04-17 15:00:51 +0300539 if (hdev->features[0][0] & LMP_3SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200540 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
541
Johan Hedbergcad718e2013-04-17 15:00:51 +0300542 if (hdev->features[0][0] & LMP_5SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200543 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
544
Johan Hedbergcad718e2013-04-17 15:00:51 +0300545 if (hdev->features[0][1] & LMP_HV2) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200546 hdev->pkt_type |= (HCI_HV2);
547 hdev->esco_type |= (ESCO_HV2);
548 }
549
Johan Hedbergcad718e2013-04-17 15:00:51 +0300550 if (hdev->features[0][1] & LMP_HV3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200551 hdev->pkt_type |= (HCI_HV3);
552 hdev->esco_type |= (ESCO_HV3);
553 }
554
Andre Guedes45db810f2012-07-24 15:03:49 -0300555 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200556 hdev->esco_type |= (ESCO_EV3);
557
Johan Hedbergcad718e2013-04-17 15:00:51 +0300558 if (hdev->features[0][4] & LMP_EV4)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200559 hdev->esco_type |= (ESCO_EV4);
560
Johan Hedbergcad718e2013-04-17 15:00:51 +0300561 if (hdev->features[0][4] & LMP_EV5)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200562 hdev->esco_type |= (ESCO_EV5);
563
Johan Hedbergcad718e2013-04-17 15:00:51 +0300564 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100565 hdev->esco_type |= (ESCO_2EV3);
566
Johan Hedbergcad718e2013-04-17 15:00:51 +0300567 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100568 hdev->esco_type |= (ESCO_3EV3);
569
Johan Hedbergcad718e2013-04-17 15:00:51 +0300570 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100571 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200572}
573
Andre Guedes971e3a42011-06-30 19:20:52 -0300574static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300575 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300576{
577 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
578
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300579 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300580
581 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200582 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300583
Marcel Holtmann57af75a2013-10-18 12:04:47 -0700584 if (hdev->max_page < rp->max_page)
585 hdev->max_page = rp->max_page;
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300586
Johan Hedbergcad718e2013-04-17 15:00:51 +0300587 if (rp->page < HCI_MAX_PAGES)
588 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300589}
590
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200591static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300592 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200593{
594 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
595
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300596 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200597
Johan Hedberg42c6b122013-03-05 20:37:49 +0200598 if (!rp->status)
599 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200600}
601
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200602static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
603{
604 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
605
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300606 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200607
608 if (rp->status)
609 return;
610
611 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
612 hdev->sco_mtu = rp->sco_mtu;
613 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
614 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
615
616 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
617 hdev->sco_mtu = 64;
618 hdev->sco_pkts = 8;
619 }
620
621 hdev->acl_cnt = hdev->acl_pkts;
622 hdev->sco_cnt = hdev->sco_pkts;
623
Gustavo Padovan807deac2012-05-17 00:36:24 -0300624 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
625 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200626}
627
628static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
629{
630 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
631
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300632 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200633
634 if (!rp->status)
635 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200636}
637
Johan Hedbergf332ec62013-03-15 17:07:11 -0500638static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
639 struct sk_buff *skb)
640{
641 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
642
643 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
644
645 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
646 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
647 hdev->page_scan_window = __le16_to_cpu(rp->window);
648 }
649}
650
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500651static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
652 struct sk_buff *skb)
653{
654 u8 status = *((u8 *) skb->data);
655 struct hci_cp_write_page_scan_activity *sent;
656
657 BT_DBG("%s status 0x%2.2x", hdev->name, status);
658
659 if (status)
660 return;
661
662 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
663 if (!sent)
664 return;
665
666 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
667 hdev->page_scan_window = __le16_to_cpu(sent->window);
668}
669
Johan Hedbergf332ec62013-03-15 17:07:11 -0500670static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
671 struct sk_buff *skb)
672{
673 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
674
675 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
676
677 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
678 hdev->page_scan_type = rp->type;
679}
680
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500681static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
682 struct sk_buff *skb)
683{
684 u8 status = *((u8 *) skb->data);
685 u8 *type;
686
687 BT_DBG("%s status 0x%2.2x", hdev->name, status);
688
689 if (status)
690 return;
691
692 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
693 if (type)
694 hdev->page_scan_type = *type;
695}
696
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200697static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300698 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200699{
700 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
701
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300702 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200703
704 if (rp->status)
705 return;
706
707 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
708 hdev->block_len = __le16_to_cpu(rp->block_len);
709 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
710
711 hdev->block_cnt = hdev->num_blocks;
712
713 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300714 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200715}
716
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300717static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300718 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300719{
720 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
721
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300722 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300723
724 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300725 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300726
727 hdev->amp_status = rp->amp_status;
728 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
729 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
730 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
731 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
732 hdev->amp_type = rp->amp_type;
733 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
734 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
735 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
736 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
737
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300738a2mp_rsp:
739 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300740}
741
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300742static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
743 struct sk_buff *skb)
744{
745 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
746 struct amp_assoc *assoc = &hdev->loc_assoc;
747 size_t rem_len, frag_len;
748
749 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
750
751 if (rp->status)
752 goto a2mp_rsp;
753
754 frag_len = skb->len - sizeof(*rp);
755 rem_len = __le16_to_cpu(rp->rem_len);
756
757 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300758 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300759
760 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
761 assoc->offset += frag_len;
762
763 /* Read other fragments */
764 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
765
766 return;
767 }
768
769 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
770 assoc->len = assoc->offset + rem_len;
771 assoc->offset = 0;
772
773a2mp_rsp:
774 /* Send A2MP Rsp when all fragments are received */
775 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300776 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300777}
778
Johan Hedbergd5859e22011-01-25 01:19:58 +0200779static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300780 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200781{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700782 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200783
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300784 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200785
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700786 if (!rp->status)
787 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200788}
789
Johan Hedberg980e1a52011-01-22 06:10:07 +0200790static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
791{
792 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
793 struct hci_cp_pin_code_reply *cp;
794 struct hci_conn *conn;
795
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300796 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200797
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200798 hci_dev_lock(hdev);
799
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200800 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200801 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200802
Mikel Astizfa1bd912012-08-09 09:52:29 +0200803 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200804 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200805
806 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
807 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200808 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200809
810 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
811 if (conn)
812 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200813
814unlock:
815 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200816}
817
818static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
819{
820 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
821
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300822 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200823
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200824 hci_dev_lock(hdev);
825
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200826 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200827 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300828 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200829
830 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200831}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200832
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300833static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
834 struct sk_buff *skb)
835{
836 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
837
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300838 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300839
840 if (rp->status)
841 return;
842
843 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
844 hdev->le_pkts = rp->le_max_pkt;
845
846 hdev->le_cnt = hdev->le_pkts;
847
848 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300849}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200850
Johan Hedberg60e77322013-01-22 14:01:59 +0200851static void hci_cc_le_read_local_features(struct hci_dev *hdev,
852 struct sk_buff *skb)
853{
854 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
855
856 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
857
858 if (!rp->status)
859 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200860}
861
Johan Hedberg8fa19092012-10-19 20:57:49 +0300862static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
863 struct sk_buff *skb)
864{
865 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
866
867 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
868
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500869 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300870 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300871}
872
Johan Hedberga5c29682011-02-19 12:05:57 -0300873static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
874{
875 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
876
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300877 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300878
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200879 hci_dev_lock(hdev);
880
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200881 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300882 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
883 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200884
885 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300886}
887
888static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300889 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300890{
891 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
892
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300893 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300894
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200895 hci_dev_lock(hdev);
896
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200897 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200898 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300899 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200900
901 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300902}
903
Brian Gix1143d452011-11-23 08:28:34 -0800904static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
905{
906 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
907
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300908 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800909
910 hci_dev_lock(hdev);
911
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200912 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200913 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300914 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800915
916 hci_dev_unlock(hdev);
917}
918
919static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300920 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800921{
922 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
923
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300924 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800925
926 hci_dev_lock(hdev);
927
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200928 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800929 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300930 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800931
932 hci_dev_unlock(hdev);
933}
934
Marcel Holtmann4d2d2792014-01-10 02:07:26 -0800935static void hci_cc_read_local_oob_data(struct hci_dev *hdev,
936 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100937{
938 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
939
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300940 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100941
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200942 hci_dev_lock(hdev);
Marcel Holtmann4d2d2792014-01-10 02:07:26 -0800943 mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->randomizer,
944 NULL, NULL, rp->status);
945 hci_dev_unlock(hdev);
946}
947
948static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev,
949 struct sk_buff *skb)
950{
951 struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data;
952
953 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
954
955 hci_dev_lock(hdev);
956 mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->randomizer192,
957 rp->hash256, rp->randomizer256,
958 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200959 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100960}
961
Marcel Holtmann7a4cd512014-02-19 19:52:13 -0800962
963static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb)
964{
965 __u8 status = *((__u8 *) skb->data);
966 bdaddr_t *sent;
967
968 BT_DBG("%s status 0x%2.2x", hdev->name, status);
969
970 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
971 if (!sent)
972 return;
973
974 hci_dev_lock(hdev);
975
976 if (!status)
977 bacpy(&hdev->random_addr, sent);
978
979 hci_dev_unlock(hdev);
980}
981
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100982static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
983{
984 __u8 *sent, status = *((__u8 *) skb->data);
985
986 BT_DBG("%s status 0x%2.2x", hdev->name, status);
987
988 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
989 if (!sent)
990 return;
991
992 hci_dev_lock(hdev);
993
Johan Hedberg778b2352014-02-24 14:52:17 +0200994 if (!status)
995 mgmt_advertising(hdev, *sent);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100996
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500997 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100998}
999
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001000static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001001 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001002{
1003 struct hci_cp_le_set_scan_enable *cp;
1004 __u8 status = *((__u8 *) skb->data);
1005
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001006 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001007
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001008 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1009 if (!cp)
1010 return;
1011
Andre Guedes3fd319b2013-04-30 15:29:36 -03001012 if (status)
1013 return;
1014
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001015 switch (cp->enable) {
Andre Guedes76a388be2013-04-04 20:21:02 -03001016 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -03001017 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001018 break;
1019
Andre Guedes76a388be2013-04-04 20:21:02 -03001020 case LE_SCAN_DISABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -03001021 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001022 break;
1023
1024 default:
1025 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1026 break;
Andre Guedes35815082011-05-26 16:23:53 -03001027 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001028}
1029
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001030static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
1031 struct sk_buff *skb)
1032{
1033 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
1034
1035 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
1036
1037 if (!rp->status)
1038 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001039}
1040
Johan Hedberg9b008c02013-01-22 14:02:01 +02001041static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
1042 struct sk_buff *skb)
1043{
1044 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
1045
1046 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1047
1048 if (!rp->status)
1049 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +02001050}
1051
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001052static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1053 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001054{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001055 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001056 __u8 status = *((__u8 *) skb->data);
1057
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001058 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001059
Johan Hedberg06199cf2012-02-22 16:37:11 +02001060 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001061 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001062 return;
1063
Johan Hedberg8f984df2012-02-28 01:07:22 +02001064 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001065 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001066 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001067 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1068 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001069 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001070 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001071 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001072 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001073
1074 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001075 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001076 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001077 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001078 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001079}
1080
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001081static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1082 struct sk_buff *skb)
1083{
1084 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1085
1086 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1087 hdev->name, rp->status, rp->phy_handle);
1088
1089 if (rp->status)
1090 return;
1091
1092 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1093}
1094
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001095static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001096{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001097 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001098
1099 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001100 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001101 return;
1102 }
1103
Andre Guedes89352e72011-11-04 14:16:53 -03001104 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001105}
1106
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001107static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001109 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001112 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001113
1114 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115 if (!cp)
1116 return;
1117
1118 hci_dev_lock(hdev);
1119
1120 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1121
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001122 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123
1124 if (status) {
1125 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001126 if (status != 0x0c || conn->attempt > 2) {
1127 conn->state = BT_CLOSED;
1128 hci_proto_connect_cfm(conn, status);
1129 hci_conn_del(conn);
1130 } else
1131 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132 }
1133 } else {
1134 if (!conn) {
1135 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1136 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001137 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138 conn->link_mode |= HCI_LM_MASTER;
1139 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001140 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 }
1142 }
1143
1144 hci_dev_unlock(hdev);
1145}
1146
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001147static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001149 struct hci_cp_add_sco *cp;
1150 struct hci_conn *acl, *sco;
1151 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001153 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001154
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001155 if (!status)
1156 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001158 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1159 if (!cp)
1160 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001162 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001164 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001165
1166 hci_dev_lock(hdev);
1167
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001168 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001169 if (acl) {
1170 sco = acl->link;
1171 if (sco) {
1172 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001173
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001174 hci_proto_connect_cfm(sco, status);
1175 hci_conn_del(sco);
1176 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001177 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001178
1179 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180}
1181
Marcel Holtmannf8558552008-07-14 20:13:49 +02001182static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1183{
1184 struct hci_cp_auth_requested *cp;
1185 struct hci_conn *conn;
1186
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001187 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001188
1189 if (!status)
1190 return;
1191
1192 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1193 if (!cp)
1194 return;
1195
1196 hci_dev_lock(hdev);
1197
1198 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1199 if (conn) {
1200 if (conn->state == BT_CONFIG) {
1201 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001202 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001203 }
1204 }
1205
1206 hci_dev_unlock(hdev);
1207}
1208
1209static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1210{
1211 struct hci_cp_set_conn_encrypt *cp;
1212 struct hci_conn *conn;
1213
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001214 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001215
1216 if (!status)
1217 return;
1218
1219 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1220 if (!cp)
1221 return;
1222
1223 hci_dev_lock(hdev);
1224
1225 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1226 if (conn) {
1227 if (conn->state == BT_CONFIG) {
1228 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001229 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001230 }
1231 }
1232
1233 hci_dev_unlock(hdev);
1234}
1235
Johan Hedberg127178d2010-11-18 22:22:29 +02001236static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001237 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001238{
Johan Hedberg392599b2010-11-18 22:22:28 +02001239 if (conn->state != BT_CONFIG || !conn->out)
1240 return 0;
1241
Johan Hedberg765c2a92011-01-19 12:06:52 +05301242 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001243 return 0;
1244
1245 /* Only request authentication for SSP connections or non-SSP
Johan Hedberg264b8b42014-01-08 16:40:39 +02001246 * devices with sec_level MEDIUM or HIGH or if MITM protection
1247 * is requested.
1248 */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001249 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
Johan Hedberg264b8b42014-01-08 16:40:39 +02001250 conn->pending_sec_level != BT_SECURITY_HIGH &&
1251 conn->pending_sec_level != BT_SECURITY_MEDIUM)
Johan Hedberg392599b2010-11-18 22:22:28 +02001252 return 0;
1253
Johan Hedberg392599b2010-11-18 22:22:28 +02001254 return 1;
1255}
1256
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001257static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001258 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001259{
1260 struct hci_cp_remote_name_req cp;
1261
1262 memset(&cp, 0, sizeof(cp));
1263
1264 bacpy(&cp.bdaddr, &e->data.bdaddr);
1265 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1266 cp.pscan_mode = e->data.pscan_mode;
1267 cp.clock_offset = e->data.clock_offset;
1268
1269 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1270}
1271
Johan Hedbergb644ba32012-01-17 21:48:47 +02001272static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001273{
1274 struct discovery_state *discov = &hdev->discovery;
1275 struct inquiry_entry *e;
1276
Johan Hedbergb644ba32012-01-17 21:48:47 +02001277 if (list_empty(&discov->resolve))
1278 return false;
1279
1280 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001281 if (!e)
1282 return false;
1283
Johan Hedbergb644ba32012-01-17 21:48:47 +02001284 if (hci_resolve_name(hdev, e) == 0) {
1285 e->name_state = NAME_PENDING;
1286 return true;
1287 }
1288
1289 return false;
1290}
1291
1292static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001293 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001294{
1295 struct discovery_state *discov = &hdev->discovery;
1296 struct inquiry_entry *e;
1297
1298 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001299 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1300 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001301
1302 if (discov->state == DISCOVERY_STOPPED)
1303 return;
1304
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001305 if (discov->state == DISCOVERY_STOPPING)
1306 goto discov_complete;
1307
1308 if (discov->state != DISCOVERY_RESOLVING)
1309 return;
1310
1311 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001312 /* If the device was not found in a list of found devices names of which
1313 * are pending. there is no need to continue resolving a next name as it
1314 * will be done upon receiving another Remote Name Request Complete
1315 * Event */
1316 if (!e)
1317 return;
1318
1319 list_del(&e->list);
1320 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001321 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001322 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1323 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001324 } else {
1325 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001326 }
1327
Johan Hedbergb644ba32012-01-17 21:48:47 +02001328 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001329 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001330
1331discov_complete:
1332 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1333}
1334
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001335static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1336{
Johan Hedberg127178d2010-11-18 22:22:29 +02001337 struct hci_cp_remote_name_req *cp;
1338 struct hci_conn *conn;
1339
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001340 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001341
1342 /* If successful wait for the name req complete event before
1343 * checking for the need to do authentication */
1344 if (!status)
1345 return;
1346
1347 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1348 if (!cp)
1349 return;
1350
1351 hci_dev_lock(hdev);
1352
1353 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001354
1355 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1356 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1357
Johan Hedberg79c6c702011-04-28 11:28:55 -07001358 if (!conn)
1359 goto unlock;
1360
1361 if (!hci_outgoing_auth_needed(hdev, conn))
1362 goto unlock;
1363
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001364 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001365 struct hci_cp_auth_requested auth_cp;
1366
1367 auth_cp.handle = __cpu_to_le16(conn->handle);
1368 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1369 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001370 }
1371
Johan Hedberg79c6c702011-04-28 11:28:55 -07001372unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001373 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001374}
1375
Marcel Holtmann769be972008-07-14 20:13:49 +02001376static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1377{
1378 struct hci_cp_read_remote_features *cp;
1379 struct hci_conn *conn;
1380
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001381 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001382
1383 if (!status)
1384 return;
1385
1386 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1387 if (!cp)
1388 return;
1389
1390 hci_dev_lock(hdev);
1391
1392 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1393 if (conn) {
1394 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001395 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001396 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001397 }
1398 }
1399
1400 hci_dev_unlock(hdev);
1401}
1402
1403static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1404{
1405 struct hci_cp_read_remote_ext_features *cp;
1406 struct hci_conn *conn;
1407
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001408 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001409
1410 if (!status)
1411 return;
1412
1413 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1414 if (!cp)
1415 return;
1416
1417 hci_dev_lock(hdev);
1418
1419 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1420 if (conn) {
1421 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001422 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001423 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001424 }
1425 }
1426
1427 hci_dev_unlock(hdev);
1428}
1429
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001430static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1431{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001432 struct hci_cp_setup_sync_conn *cp;
1433 struct hci_conn *acl, *sco;
1434 __u16 handle;
1435
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001436 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001437
1438 if (!status)
1439 return;
1440
1441 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1442 if (!cp)
1443 return;
1444
1445 handle = __le16_to_cpu(cp->handle);
1446
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001447 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001448
1449 hci_dev_lock(hdev);
1450
1451 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001452 if (acl) {
1453 sco = acl->link;
1454 if (sco) {
1455 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001456
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001457 hci_proto_connect_cfm(sco, status);
1458 hci_conn_del(sco);
1459 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001460 }
1461
1462 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001463}
1464
1465static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1466{
1467 struct hci_cp_sniff_mode *cp;
1468 struct hci_conn *conn;
1469
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001470 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001471
1472 if (!status)
1473 return;
1474
1475 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1476 if (!cp)
1477 return;
1478
1479 hci_dev_lock(hdev);
1480
1481 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001482 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001483 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001484
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001485 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001486 hci_sco_setup(conn, status);
1487 }
1488
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001489 hci_dev_unlock(hdev);
1490}
1491
1492static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1493{
1494 struct hci_cp_exit_sniff_mode *cp;
1495 struct hci_conn *conn;
1496
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001497 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001498
1499 if (!status)
1500 return;
1501
1502 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1503 if (!cp)
1504 return;
1505
1506 hci_dev_lock(hdev);
1507
1508 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001509 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001510 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001511
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001512 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001513 hci_sco_setup(conn, status);
1514 }
1515
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001516 hci_dev_unlock(hdev);
1517}
1518
Johan Hedberg88c3df12012-02-09 14:27:38 +02001519static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1520{
1521 struct hci_cp_disconnect *cp;
1522 struct hci_conn *conn;
1523
1524 if (!status)
1525 return;
1526
1527 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1528 if (!cp)
1529 return;
1530
1531 hci_dev_lock(hdev);
1532
1533 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1534 if (conn)
1535 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001536 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001537
1538 hci_dev_unlock(hdev);
1539}
1540
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001541static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1542{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001543 struct hci_cp_create_phy_link *cp;
1544
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001545 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001546
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001547 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1548 if (!cp)
1549 return;
1550
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001551 hci_dev_lock(hdev);
1552
1553 if (status) {
1554 struct hci_conn *hcon;
1555
1556 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1557 if (hcon)
1558 hci_conn_del(hcon);
1559 } else {
1560 amp_write_remote_assoc(hdev, cp->phy_handle);
1561 }
1562
1563 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001564}
1565
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001566static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1567{
1568 struct hci_cp_accept_phy_link *cp;
1569
1570 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1571
1572 if (status)
1573 return;
1574
1575 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1576 if (!cp)
1577 return;
1578
1579 amp_write_remote_assoc(hdev, cp->phy_handle);
1580}
1581
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001582static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001583{
1584 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001585 struct discovery_state *discov = &hdev->discovery;
1586 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001587
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001588 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001589
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001590 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001591
1592 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1593 return;
1594
Andre Guedes3e13fa12013-03-27 20:04:56 -03001595 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1596 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1597
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001598 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001599 return;
1600
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001601 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001602
Andre Guedes343f9352012-02-17 20:39:37 -03001603 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001604 goto unlock;
1605
1606 if (list_empty(&discov->resolve)) {
1607 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1608 goto unlock;
1609 }
1610
1611 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1612 if (e && hci_resolve_name(hdev, e) == 0) {
1613 e->name_state = NAME_PENDING;
1614 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1615 } else {
1616 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1617 }
1618
1619unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001620 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001621}
1622
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001623static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001625 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001626 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 int num_rsp = *((__u8 *) skb->data);
1628
1629 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1630
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001631 if (!num_rsp)
1632 return;
1633
Andre Guedes1519cc12012-03-21 00:03:38 -03001634 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1635 return;
1636
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001638
Johan Hedberge17acd42011-03-30 23:57:16 +03001639 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001640 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001641
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642 bacpy(&data.bdaddr, &info->bdaddr);
1643 data.pscan_rep_mode = info->pscan_rep_mode;
1644 data.pscan_period_mode = info->pscan_period_mode;
1645 data.pscan_mode = info->pscan_mode;
1646 memcpy(data.dev_class, info->dev_class, 3);
1647 data.clock_offset = info->clock_offset;
1648 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001649 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001650
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001651 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001652 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001653 info->dev_class, 0, !name_known, ssp, NULL,
1654 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001656
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657 hci_dev_unlock(hdev);
1658}
1659
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001660static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001662 struct hci_ev_conn_complete *ev = (void *) skb->data;
1663 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001665 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001666
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001668
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001669 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001670 if (!conn) {
1671 if (ev->link_type != SCO_LINK)
1672 goto unlock;
1673
1674 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1675 if (!conn)
1676 goto unlock;
1677
1678 conn->type = SCO_LINK;
1679 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001680
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001681 if (!ev->status) {
1682 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001683
1684 if (conn->type == ACL_LINK) {
1685 conn->state = BT_CONFIG;
1686 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001687
1688 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1689 !hci_find_link_key(hdev, &ev->bdaddr))
1690 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1691 else
1692 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001693 } else
1694 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001695
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001696 hci_conn_add_sysfs(conn);
1697
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001698 if (test_bit(HCI_AUTH, &hdev->flags))
1699 conn->link_mode |= HCI_LM_AUTH;
1700
1701 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1702 conn->link_mode |= HCI_LM_ENCRYPT;
1703
1704 /* Get remote features */
1705 if (conn->type == ACL_LINK) {
1706 struct hci_cp_read_remote_features cp;
1707 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001708 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001709 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001710 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001711
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001712 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001713 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001714 struct hci_cp_change_conn_ptype cp;
1715 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001716 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001717 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1718 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001719 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001720 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001721 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001722 if (conn->type == ACL_LINK)
Marcel Holtmann64c7b772014-02-18 14:22:20 -08001723 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001724 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001725 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001726
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001727 if (conn->type == ACL_LINK)
1728 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001729
Marcel Holtmann769be972008-07-14 20:13:49 +02001730 if (ev->status) {
1731 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001732 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001733 } else if (ev->link_type != ACL_LINK)
1734 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001735
1736unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001738
1739 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740}
1741
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001742static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001744 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 int mask = hdev->link_mode;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001746 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001748 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001749 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001751 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1752 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753
Szymon Janc138d22e2011-02-17 16:44:23 +01001754 if ((mask & HCI_LM_ACCEPT) &&
Marcel Holtmannb9ee0a72013-10-17 17:24:13 -07001755 !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001757 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759
1760 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001761
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001762 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1763 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001764 memcpy(ie->data.dev_class, ev->dev_class, 3);
1765
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001766 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1767 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001769 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1770 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001771 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 hci_dev_unlock(hdev);
1773 return;
1774 }
1775 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001776
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001778
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 hci_dev_unlock(hdev);
1780
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001781 if (ev->link_type == ACL_LINK ||
1782 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001783 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001784 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001786 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001788 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1789 cp.role = 0x00; /* Become master */
1790 else
1791 cp.role = 0x01; /* Remain slave */
1792
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001793 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1794 &cp);
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001795 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001796 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001797 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001798
1799 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001800 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001801
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001802 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1803 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1804 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001805 cp.content_format = cpu_to_le16(hdev->voice_setting);
1806 cp.retrans_effort = 0xff;
1807
1808 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001809 sizeof(cp), &cp);
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001810 } else {
1811 conn->state = BT_CONNECT2;
1812 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001813 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 } else {
1815 /* Connection rejected */
1816 struct hci_cp_reject_conn_req cp;
1817
1818 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001819 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001820 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821 }
1822}
1823
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001824static u8 hci_to_mgmt_reason(u8 err)
1825{
1826 switch (err) {
1827 case HCI_ERROR_CONNECTION_TIMEOUT:
1828 return MGMT_DEV_DISCONN_TIMEOUT;
1829 case HCI_ERROR_REMOTE_USER_TERM:
1830 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1831 case HCI_ERROR_REMOTE_POWER_OFF:
1832 return MGMT_DEV_DISCONN_REMOTE;
1833 case HCI_ERROR_LOCAL_HOST_TERM:
1834 return MGMT_DEV_DISCONN_LOCAL_HOST;
1835 default:
1836 return MGMT_DEV_DISCONN_UNKNOWN;
1837 }
1838}
1839
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001840static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001842 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Andre Guedesabf54a52013-11-07 17:36:09 -03001843 u8 reason = hci_to_mgmt_reason(ev->reason);
Andre Guedes9fcb18e2014-02-26 20:21:48 -03001844 struct hci_conn_params *params;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001845 struct hci_conn *conn;
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02001846 bool mgmt_connected;
Andre Guedes38462202013-11-07 17:36:10 -03001847 u8 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001849 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 hci_dev_lock(hdev);
1852
Marcel Holtmann04837f62006-07-03 10:02:33 +02001853 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001854 if (!conn)
1855 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001856
Andre Guedesabf54a52013-11-07 17:36:09 -03001857 if (ev->status) {
1858 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1859 conn->dst_type, ev->status);
1860 goto unlock;
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001861 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001862
Andre Guedes38462202013-11-07 17:36:10 -03001863 conn->state = BT_CLOSED;
1864
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02001865 mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
1866 mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
1867 reason, mgmt_connected);
Andre Guedesabf54a52013-11-07 17:36:09 -03001868
Andre Guedes38462202013-11-07 17:36:10 -03001869 if (conn->type == ACL_LINK && conn->flush_key)
1870 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg22102462013-10-05 12:01:06 +02001871
Andre Guedes9fcb18e2014-02-26 20:21:48 -03001872 params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
1873 if (params) {
1874 switch (params->auto_connect) {
1875 case HCI_AUTO_CONN_LINK_LOSS:
1876 if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
1877 break;
1878 /* Fall through */
1879
1880 case HCI_AUTO_CONN_ALWAYS:
1881 hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type);
1882 break;
1883
1884 default:
1885 break;
1886 }
1887 }
1888
Andre Guedes38462202013-11-07 17:36:10 -03001889 type = conn->type;
Johan Hedberg22102462013-10-05 12:01:06 +02001890
Andre Guedes38462202013-11-07 17:36:10 -03001891 hci_proto_disconn_cfm(conn, ev->reason);
1892 hci_conn_del(conn);
1893
1894 /* Re-enable advertising if necessary, since it might
1895 * have been disabled by the connection. From the
1896 * HCI_LE_Set_Advertise_Enable command description in
1897 * the core specification (v4.0):
1898 * "The Controller shall continue advertising until the Host
1899 * issues an LE_Set_Advertise_Enable command with
1900 * Advertising_Enable set to 0x00 (Advertising is disabled)
1901 * or until a connection is created or until the Advertising
1902 * is timed out due to Directed Advertising."
1903 */
1904 if (type == LE_LINK)
1905 mgmt_reenable_advertising(hdev);
Johan Hedbergf7520542011-01-20 12:34:39 +02001906
1907unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908 hci_dev_unlock(hdev);
1909}
1910
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001911static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001912{
1913 struct hci_ev_auth_complete *ev = (void *) skb->data;
1914 struct hci_conn *conn;
1915
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001916 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001917
1918 hci_dev_lock(hdev);
1919
1920 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001921 if (!conn)
1922 goto unlock;
1923
1924 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001925 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001926 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001927 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001928 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001929 conn->link_mode |= HCI_LM_AUTH;
1930 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001931 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001932 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001933 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001934 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001935 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001936
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001937 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1938 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001939
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001940 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001941 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001942 struct hci_cp_set_conn_encrypt cp;
1943 cp.handle = ev->handle;
1944 cp.encrypt = 0x01;
1945 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001946 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001947 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001948 conn->state = BT_CONNECTED;
1949 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001950 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001951 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001952 } else {
1953 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001954
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001955 hci_conn_hold(conn);
1956 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001957 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001958 }
1959
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001960 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001961 if (!ev->status) {
1962 struct hci_cp_set_conn_encrypt cp;
1963 cp.handle = ev->handle;
1964 cp.encrypt = 0x01;
1965 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001966 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001967 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001968 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001969 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001970 }
1971 }
1972
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001973unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001974 hci_dev_unlock(hdev);
1975}
1976
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001977static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001978{
Johan Hedberg127178d2010-11-18 22:22:29 +02001979 struct hci_ev_remote_name *ev = (void *) skb->data;
1980 struct hci_conn *conn;
1981
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001982 BT_DBG("%s", hdev->name);
1983
1984 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001985
1986 hci_dev_lock(hdev);
1987
1988 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001989
1990 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1991 goto check_auth;
1992
1993 if (ev->status == 0)
1994 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001995 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001996 else
1997 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1998
1999check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002000 if (!conn)
2001 goto unlock;
2002
2003 if (!hci_outgoing_auth_needed(hdev, conn))
2004 goto unlock;
2005
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002006 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002007 struct hci_cp_auth_requested cp;
2008 cp.handle = __cpu_to_le16(conn->handle);
2009 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2010 }
2011
Johan Hedberg79c6c702011-04-28 11:28:55 -07002012unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002013 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002014}
2015
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002016static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002017{
2018 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2019 struct hci_conn *conn;
2020
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002021 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002022
2023 hci_dev_lock(hdev);
2024
2025 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002026 if (!conn)
2027 goto unlock;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002028
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002029 if (!ev->status) {
2030 if (ev->encrypt) {
2031 /* Encryption implies authentication */
2032 conn->link_mode |= HCI_LM_AUTH;
2033 conn->link_mode |= HCI_LM_ENCRYPT;
2034 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002035
Marcel Holtmann914a6ff2014-02-01 11:52:02 -08002036 /* P-256 authentication key implies FIPS */
2037 if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
2038 conn->link_mode |= HCI_LM_FIPS;
2039
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002040 if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
2041 conn->type == LE_LINK)
2042 set_bit(HCI_CONN_AES_CCM, &conn->flags);
2043 } else {
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002044 conn->link_mode &= ~HCI_LM_ENCRYPT;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002045 clear_bit(HCI_CONN_AES_CCM, &conn->flags);
2046 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002047 }
2048
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002049 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2050
2051 if (ev->status && conn->state == BT_CONNECTED) {
2052 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
2053 hci_conn_drop(conn);
2054 goto unlock;
2055 }
2056
2057 if (conn->state == BT_CONFIG) {
2058 if (!ev->status)
2059 conn->state = BT_CONNECTED;
2060
2061 hci_proto_connect_cfm(conn, ev->status);
2062 hci_conn_drop(conn);
2063 } else
2064 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
2065
Gustavo Padovana7d77232012-05-13 03:20:07 -03002066unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002067 hci_dev_unlock(hdev);
2068}
2069
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002070static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2071 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002072{
2073 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2074 struct hci_conn *conn;
2075
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002076 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002077
2078 hci_dev_lock(hdev);
2079
2080 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2081 if (conn) {
2082 if (!ev->status)
2083 conn->link_mode |= HCI_LM_SECURE;
2084
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002085 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002086
2087 hci_key_change_cfm(conn, ev->status);
2088 }
2089
2090 hci_dev_unlock(hdev);
2091}
2092
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002093static void hci_remote_features_evt(struct hci_dev *hdev,
2094 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002095{
2096 struct hci_ev_remote_features *ev = (void *) skb->data;
2097 struct hci_conn *conn;
2098
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002099 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002100
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002101 hci_dev_lock(hdev);
2102
2103 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002104 if (!conn)
2105 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002106
Johan Hedbergccd556f2010-11-10 17:11:51 +02002107 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002108 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002109
2110 if (conn->state != BT_CONFIG)
2111 goto unlock;
2112
2113 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2114 struct hci_cp_read_remote_ext_features cp;
2115 cp.handle = ev->handle;
2116 cp.page = 0x01;
2117 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002118 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002119 goto unlock;
2120 }
2121
Johan Hedberg671267b2012-05-12 16:11:50 -03002122 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002123 struct hci_cp_remote_name_req cp;
2124 memset(&cp, 0, sizeof(cp));
2125 bacpy(&cp.bdaddr, &conn->dst);
2126 cp.pscan_rep_mode = 0x02;
2127 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002128 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2129 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002130 conn->dst_type, 0, NULL, 0,
2131 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002132
Johan Hedberg127178d2010-11-18 22:22:29 +02002133 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002134 conn->state = BT_CONNECTED;
2135 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002136 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002137 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002138
Johan Hedbergccd556f2010-11-10 17:11:51 +02002139unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002140 hci_dev_unlock(hdev);
2141}
2142
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002143static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002144{
2145 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002146 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002147 __u16 opcode;
2148
2149 skb_pull(skb, sizeof(*ev));
2150
2151 opcode = __le16_to_cpu(ev->opcode);
2152
2153 switch (opcode) {
2154 case HCI_OP_INQUIRY_CANCEL:
2155 hci_cc_inquiry_cancel(hdev, skb);
2156 break;
2157
Andre Guedes4d934832012-03-21 00:03:35 -03002158 case HCI_OP_PERIODIC_INQ:
2159 hci_cc_periodic_inq(hdev, skb);
2160 break;
2161
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002162 case HCI_OP_EXIT_PERIODIC_INQ:
2163 hci_cc_exit_periodic_inq(hdev, skb);
2164 break;
2165
2166 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2167 hci_cc_remote_name_req_cancel(hdev, skb);
2168 break;
2169
2170 case HCI_OP_ROLE_DISCOVERY:
2171 hci_cc_role_discovery(hdev, skb);
2172 break;
2173
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002174 case HCI_OP_READ_LINK_POLICY:
2175 hci_cc_read_link_policy(hdev, skb);
2176 break;
2177
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002178 case HCI_OP_WRITE_LINK_POLICY:
2179 hci_cc_write_link_policy(hdev, skb);
2180 break;
2181
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002182 case HCI_OP_READ_DEF_LINK_POLICY:
2183 hci_cc_read_def_link_policy(hdev, skb);
2184 break;
2185
2186 case HCI_OP_WRITE_DEF_LINK_POLICY:
2187 hci_cc_write_def_link_policy(hdev, skb);
2188 break;
2189
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002190 case HCI_OP_RESET:
2191 hci_cc_reset(hdev, skb);
2192 break;
2193
2194 case HCI_OP_WRITE_LOCAL_NAME:
2195 hci_cc_write_local_name(hdev, skb);
2196 break;
2197
2198 case HCI_OP_READ_LOCAL_NAME:
2199 hci_cc_read_local_name(hdev, skb);
2200 break;
2201
2202 case HCI_OP_WRITE_AUTH_ENABLE:
2203 hci_cc_write_auth_enable(hdev, skb);
2204 break;
2205
2206 case HCI_OP_WRITE_ENCRYPT_MODE:
2207 hci_cc_write_encrypt_mode(hdev, skb);
2208 break;
2209
2210 case HCI_OP_WRITE_SCAN_ENABLE:
2211 hci_cc_write_scan_enable(hdev, skb);
2212 break;
2213
2214 case HCI_OP_READ_CLASS_OF_DEV:
2215 hci_cc_read_class_of_dev(hdev, skb);
2216 break;
2217
2218 case HCI_OP_WRITE_CLASS_OF_DEV:
2219 hci_cc_write_class_of_dev(hdev, skb);
2220 break;
2221
2222 case HCI_OP_READ_VOICE_SETTING:
2223 hci_cc_read_voice_setting(hdev, skb);
2224 break;
2225
2226 case HCI_OP_WRITE_VOICE_SETTING:
2227 hci_cc_write_voice_setting(hdev, skb);
2228 break;
2229
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002230 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2231 hci_cc_read_num_supported_iac(hdev, skb);
2232 break;
2233
Marcel Holtmann333140b2008-07-14 20:13:48 +02002234 case HCI_OP_WRITE_SSP_MODE:
2235 hci_cc_write_ssp_mode(hdev, skb);
2236 break;
2237
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08002238 case HCI_OP_WRITE_SC_SUPPORT:
2239 hci_cc_write_sc_support(hdev, skb);
2240 break;
2241
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002242 case HCI_OP_READ_LOCAL_VERSION:
2243 hci_cc_read_local_version(hdev, skb);
2244 break;
2245
2246 case HCI_OP_READ_LOCAL_COMMANDS:
2247 hci_cc_read_local_commands(hdev, skb);
2248 break;
2249
2250 case HCI_OP_READ_LOCAL_FEATURES:
2251 hci_cc_read_local_features(hdev, skb);
2252 break;
2253
Andre Guedes971e3a42011-06-30 19:20:52 -03002254 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2255 hci_cc_read_local_ext_features(hdev, skb);
2256 break;
2257
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002258 case HCI_OP_READ_BUFFER_SIZE:
2259 hci_cc_read_buffer_size(hdev, skb);
2260 break;
2261
2262 case HCI_OP_READ_BD_ADDR:
2263 hci_cc_read_bd_addr(hdev, skb);
2264 break;
2265
Johan Hedbergf332ec62013-03-15 17:07:11 -05002266 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2267 hci_cc_read_page_scan_activity(hdev, skb);
2268 break;
2269
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002270 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2271 hci_cc_write_page_scan_activity(hdev, skb);
2272 break;
2273
Johan Hedbergf332ec62013-03-15 17:07:11 -05002274 case HCI_OP_READ_PAGE_SCAN_TYPE:
2275 hci_cc_read_page_scan_type(hdev, skb);
2276 break;
2277
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002278 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2279 hci_cc_write_page_scan_type(hdev, skb);
2280 break;
2281
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002282 case HCI_OP_READ_DATA_BLOCK_SIZE:
2283 hci_cc_read_data_block_size(hdev, skb);
2284 break;
2285
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002286 case HCI_OP_READ_FLOW_CONTROL_MODE:
2287 hci_cc_read_flow_control_mode(hdev, skb);
2288 break;
2289
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002290 case HCI_OP_READ_LOCAL_AMP_INFO:
2291 hci_cc_read_local_amp_info(hdev, skb);
2292 break;
2293
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002294 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2295 hci_cc_read_local_amp_assoc(hdev, skb);
2296 break;
2297
Johan Hedbergd5859e22011-01-25 01:19:58 +02002298 case HCI_OP_READ_INQ_RSP_TX_POWER:
2299 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2300 break;
2301
Johan Hedberg980e1a52011-01-22 06:10:07 +02002302 case HCI_OP_PIN_CODE_REPLY:
2303 hci_cc_pin_code_reply(hdev, skb);
2304 break;
2305
2306 case HCI_OP_PIN_CODE_NEG_REPLY:
2307 hci_cc_pin_code_neg_reply(hdev, skb);
2308 break;
2309
Szymon Jancc35938b2011-03-22 13:12:21 +01002310 case HCI_OP_READ_LOCAL_OOB_DATA:
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08002311 hci_cc_read_local_oob_data(hdev, skb);
2312 break;
2313
2314 case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
2315 hci_cc_read_local_oob_ext_data(hdev, skb);
Szymon Jancc35938b2011-03-22 13:12:21 +01002316 break;
2317
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002318 case HCI_OP_LE_READ_BUFFER_SIZE:
2319 hci_cc_le_read_buffer_size(hdev, skb);
2320 break;
2321
Johan Hedberg60e77322013-01-22 14:01:59 +02002322 case HCI_OP_LE_READ_LOCAL_FEATURES:
2323 hci_cc_le_read_local_features(hdev, skb);
2324 break;
2325
Johan Hedberg8fa19092012-10-19 20:57:49 +03002326 case HCI_OP_LE_READ_ADV_TX_POWER:
2327 hci_cc_le_read_adv_tx_power(hdev, skb);
2328 break;
2329
Johan Hedberga5c29682011-02-19 12:05:57 -03002330 case HCI_OP_USER_CONFIRM_REPLY:
2331 hci_cc_user_confirm_reply(hdev, skb);
2332 break;
2333
2334 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2335 hci_cc_user_confirm_neg_reply(hdev, skb);
2336 break;
2337
Brian Gix1143d452011-11-23 08:28:34 -08002338 case HCI_OP_USER_PASSKEY_REPLY:
2339 hci_cc_user_passkey_reply(hdev, skb);
2340 break;
2341
2342 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2343 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002344 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002345
Marcel Holtmann7a4cd512014-02-19 19:52:13 -08002346 case HCI_OP_LE_SET_RANDOM_ADDR:
2347 hci_cc_le_set_random_addr(hdev, skb);
2348 break;
2349
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002350 case HCI_OP_LE_SET_ADV_ENABLE:
2351 hci_cc_le_set_adv_enable(hdev, skb);
2352 break;
2353
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002354 case HCI_OP_LE_SET_SCAN_ENABLE:
2355 hci_cc_le_set_scan_enable(hdev, skb);
2356 break;
2357
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002358 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2359 hci_cc_le_read_white_list_size(hdev, skb);
2360 break;
2361
Johan Hedberg9b008c02013-01-22 14:02:01 +02002362 case HCI_OP_LE_READ_SUPPORTED_STATES:
2363 hci_cc_le_read_supported_states(hdev, skb);
2364 break;
2365
Andre Guedesf9b49302011-06-30 19:20:53 -03002366 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2367 hci_cc_write_le_host_supported(hdev, skb);
2368 break;
2369
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002370 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2371 hci_cc_write_remote_amp_assoc(hdev, skb);
2372 break;
2373
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002374 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002375 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002376 break;
2377 }
2378
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002379 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002380 del_timer(&hdev->cmd_timer);
2381
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002382 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002383
Szymon Jancdbccd792012-12-11 08:51:19 +01002384 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002385 atomic_set(&hdev->cmd_cnt, 1);
2386 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002387 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002388 }
2389}
2390
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002391static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002392{
2393 struct hci_ev_cmd_status *ev = (void *) skb->data;
2394 __u16 opcode;
2395
2396 skb_pull(skb, sizeof(*ev));
2397
2398 opcode = __le16_to_cpu(ev->opcode);
2399
2400 switch (opcode) {
2401 case HCI_OP_INQUIRY:
2402 hci_cs_inquiry(hdev, ev->status);
2403 break;
2404
2405 case HCI_OP_CREATE_CONN:
2406 hci_cs_create_conn(hdev, ev->status);
2407 break;
2408
2409 case HCI_OP_ADD_SCO:
2410 hci_cs_add_sco(hdev, ev->status);
2411 break;
2412
Marcel Holtmannf8558552008-07-14 20:13:49 +02002413 case HCI_OP_AUTH_REQUESTED:
2414 hci_cs_auth_requested(hdev, ev->status);
2415 break;
2416
2417 case HCI_OP_SET_CONN_ENCRYPT:
2418 hci_cs_set_conn_encrypt(hdev, ev->status);
2419 break;
2420
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002421 case HCI_OP_REMOTE_NAME_REQ:
2422 hci_cs_remote_name_req(hdev, ev->status);
2423 break;
2424
Marcel Holtmann769be972008-07-14 20:13:49 +02002425 case HCI_OP_READ_REMOTE_FEATURES:
2426 hci_cs_read_remote_features(hdev, ev->status);
2427 break;
2428
2429 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2430 hci_cs_read_remote_ext_features(hdev, ev->status);
2431 break;
2432
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002433 case HCI_OP_SETUP_SYNC_CONN:
2434 hci_cs_setup_sync_conn(hdev, ev->status);
2435 break;
2436
2437 case HCI_OP_SNIFF_MODE:
2438 hci_cs_sniff_mode(hdev, ev->status);
2439 break;
2440
2441 case HCI_OP_EXIT_SNIFF_MODE:
2442 hci_cs_exit_sniff_mode(hdev, ev->status);
2443 break;
2444
Johan Hedberg8962ee72011-01-20 12:40:27 +02002445 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002446 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002447 break;
2448
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002449 case HCI_OP_CREATE_PHY_LINK:
2450 hci_cs_create_phylink(hdev, ev->status);
2451 break;
2452
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002453 case HCI_OP_ACCEPT_PHY_LINK:
2454 hci_cs_accept_phylink(hdev, ev->status);
2455 break;
2456
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002457 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002458 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002459 break;
2460 }
2461
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002462 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002463 del_timer(&hdev->cmd_timer);
2464
Johan Hedberg02350a72013-04-03 21:50:29 +03002465 if (ev->status ||
2466 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2467 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002468
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002469 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002470 atomic_set(&hdev->cmd_cnt, 1);
2471 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002472 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002473 }
2474}
2475
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002476static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002477{
2478 struct hci_ev_role_change *ev = (void *) skb->data;
2479 struct hci_conn *conn;
2480
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002481 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002482
2483 hci_dev_lock(hdev);
2484
2485 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2486 if (conn) {
2487 if (!ev->status) {
2488 if (ev->role)
2489 conn->link_mode &= ~HCI_LM_MASTER;
2490 else
2491 conn->link_mode |= HCI_LM_MASTER;
2492 }
2493
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002494 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002495
2496 hci_role_switch_cfm(conn, ev->status, ev->role);
2497 }
2498
2499 hci_dev_unlock(hdev);
2500}
2501
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002502static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002504 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505 int i;
2506
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002507 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2508 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2509 return;
2510 }
2511
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002512 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002513 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002514 BT_DBG("%s bad parameters", hdev->name);
2515 return;
2516 }
2517
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002518 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2519
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002520 for (i = 0; i < ev->num_hndl; i++) {
2521 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522 struct hci_conn *conn;
2523 __u16 handle, count;
2524
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002525 handle = __le16_to_cpu(info->handle);
2526 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002527
2528 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002529 if (!conn)
2530 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002531
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002532 conn->sent -= count;
2533
2534 switch (conn->type) {
2535 case ACL_LINK:
2536 hdev->acl_cnt += count;
2537 if (hdev->acl_cnt > hdev->acl_pkts)
2538 hdev->acl_cnt = hdev->acl_pkts;
2539 break;
2540
2541 case LE_LINK:
2542 if (hdev->le_pkts) {
2543 hdev->le_cnt += count;
2544 if (hdev->le_cnt > hdev->le_pkts)
2545 hdev->le_cnt = hdev->le_pkts;
2546 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002547 hdev->acl_cnt += count;
2548 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002549 hdev->acl_cnt = hdev->acl_pkts;
2550 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002551 break;
2552
2553 case SCO_LINK:
2554 hdev->sco_cnt += count;
2555 if (hdev->sco_cnt > hdev->sco_pkts)
2556 hdev->sco_cnt = hdev->sco_pkts;
2557 break;
2558
2559 default:
2560 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2561 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002562 }
2563 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002564
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002565 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566}
2567
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002568static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2569 __u16 handle)
2570{
2571 struct hci_chan *chan;
2572
2573 switch (hdev->dev_type) {
2574 case HCI_BREDR:
2575 return hci_conn_hash_lookup_handle(hdev, handle);
2576 case HCI_AMP:
2577 chan = hci_chan_lookup_handle(hdev, handle);
2578 if (chan)
2579 return chan->conn;
2580 break;
2581 default:
2582 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2583 break;
2584 }
2585
2586 return NULL;
2587}
2588
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002589static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002590{
2591 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2592 int i;
2593
2594 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2595 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2596 return;
2597 }
2598
2599 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002600 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002601 BT_DBG("%s bad parameters", hdev->name);
2602 return;
2603 }
2604
2605 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002606 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002607
2608 for (i = 0; i < ev->num_hndl; i++) {
2609 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002610 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002611 __u16 handle, block_count;
2612
2613 handle = __le16_to_cpu(info->handle);
2614 block_count = __le16_to_cpu(info->blocks);
2615
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002616 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002617 if (!conn)
2618 continue;
2619
2620 conn->sent -= block_count;
2621
2622 switch (conn->type) {
2623 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002624 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002625 hdev->block_cnt += block_count;
2626 if (hdev->block_cnt > hdev->num_blocks)
2627 hdev->block_cnt = hdev->num_blocks;
2628 break;
2629
2630 default:
2631 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2632 break;
2633 }
2634 }
2635
2636 queue_work(hdev->workqueue, &hdev->tx_work);
2637}
2638
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002639static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002641 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002642 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002643
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002644 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002645
2646 hci_dev_lock(hdev);
2647
Marcel Holtmann04837f62006-07-03 10:02:33 +02002648 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2649 if (conn) {
2650 conn->mode = ev->mode;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002651
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002652 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2653 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002654 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002655 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002656 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002657 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002658 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002659
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002660 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002661 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002662 }
2663
2664 hci_dev_unlock(hdev);
2665}
2666
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002667static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002668{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002669 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2670 struct hci_conn *conn;
2671
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002672 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002673
2674 hci_dev_lock(hdev);
2675
2676 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002677 if (!conn)
2678 goto unlock;
2679
2680 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002681 hci_conn_hold(conn);
2682 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002683 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002684 }
2685
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002686 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002687 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002688 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002689 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002690 u8 secure;
2691
2692 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2693 secure = 1;
2694 else
2695 secure = 0;
2696
Johan Hedberg744cf192011-11-08 20:40:14 +02002697 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002698 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002699
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002700unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002701 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002702}
2703
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002704static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002706 struct hci_ev_link_key_req *ev = (void *) skb->data;
2707 struct hci_cp_link_key_reply cp;
2708 struct hci_conn *conn;
2709 struct link_key *key;
2710
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002711 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002712
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002713 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002714 return;
2715
2716 hci_dev_lock(hdev);
2717
2718 key = hci_find_link_key(hdev, &ev->bdaddr);
2719 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002720 BT_DBG("%s link key not found for %pMR", hdev->name,
2721 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002722 goto not_found;
2723 }
2724
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002725 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2726 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002727
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002728 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002729 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002730 BT_DBG("%s ignoring debug key", hdev->name);
2731 goto not_found;
2732 }
2733
2734 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002735 if (conn) {
Marcel Holtmann66138ce2014-01-10 02:07:20 -08002736 if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
2737 key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002738 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002739 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2740 goto not_found;
2741 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002742
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002743 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002744 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002745 BT_DBG("%s ignoring key unauthenticated for high security",
2746 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002747 goto not_found;
2748 }
2749
2750 conn->key_type = key->type;
2751 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002752 }
2753
2754 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002755 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002756
2757 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2758
2759 hci_dev_unlock(hdev);
2760
2761 return;
2762
2763not_found:
2764 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2765 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002766}
2767
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002768static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002769{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002770 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2771 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002772 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002773
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002774 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002775
2776 hci_dev_lock(hdev);
2777
2778 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2779 if (conn) {
2780 hci_conn_hold(conn);
2781 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002782 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002783
2784 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2785 conn->key_type = ev->key_type;
2786
David Herrmann76a68ba2013-04-06 20:28:37 +02002787 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002788 }
2789
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002790 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002791 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002792 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002793
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002794 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002795}
2796
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002797static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002798{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002799 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002800 struct hci_conn *conn;
2801
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002802 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002803
2804 hci_dev_lock(hdev);
2805
2806 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002807 if (conn && !ev->status) {
2808 struct inquiry_entry *ie;
2809
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002810 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2811 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002812 ie->data.clock_offset = ev->clock_offset;
2813 ie->timestamp = jiffies;
2814 }
2815 }
2816
2817 hci_dev_unlock(hdev);
2818}
2819
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002820static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002821{
2822 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2823 struct hci_conn *conn;
2824
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002825 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002826
2827 hci_dev_lock(hdev);
2828
2829 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2830 if (conn && !ev->status)
2831 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2832
2833 hci_dev_unlock(hdev);
2834}
2835
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002836static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002837{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002838 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002839 struct inquiry_entry *ie;
2840
2841 BT_DBG("%s", hdev->name);
2842
2843 hci_dev_lock(hdev);
2844
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002845 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2846 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002847 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2848 ie->timestamp = jiffies;
2849 }
2850
2851 hci_dev_unlock(hdev);
2852}
2853
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002854static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2855 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002856{
2857 struct inquiry_data data;
2858 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002859 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002860
2861 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2862
2863 if (!num_rsp)
2864 return;
2865
Andre Guedes1519cc12012-03-21 00:03:38 -03002866 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2867 return;
2868
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002869 hci_dev_lock(hdev);
2870
2871 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002872 struct inquiry_info_with_rssi_and_pscan_mode *info;
2873 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002874
Johan Hedberge17acd42011-03-30 23:57:16 +03002875 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002876 bacpy(&data.bdaddr, &info->bdaddr);
2877 data.pscan_rep_mode = info->pscan_rep_mode;
2878 data.pscan_period_mode = info->pscan_period_mode;
2879 data.pscan_mode = info->pscan_mode;
2880 memcpy(data.dev_class, info->dev_class, 3);
2881 data.clock_offset = info->clock_offset;
2882 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002883 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002884
2885 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002886 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002887 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002888 info->dev_class, info->rssi,
2889 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002890 }
2891 } else {
2892 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2893
Johan Hedberge17acd42011-03-30 23:57:16 +03002894 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002895 bacpy(&data.bdaddr, &info->bdaddr);
2896 data.pscan_rep_mode = info->pscan_rep_mode;
2897 data.pscan_period_mode = info->pscan_period_mode;
2898 data.pscan_mode = 0x00;
2899 memcpy(data.dev_class, info->dev_class, 3);
2900 data.clock_offset = info->clock_offset;
2901 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002902 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002903 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002904 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002905 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002906 info->dev_class, info->rssi,
2907 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002908 }
2909 }
2910
2911 hci_dev_unlock(hdev);
2912}
2913
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002914static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2915 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002916{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002917 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2918 struct hci_conn *conn;
2919
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002920 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002921
Marcel Holtmann41a96212008-07-14 20:13:48 +02002922 hci_dev_lock(hdev);
2923
2924 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002925 if (!conn)
2926 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002927
Johan Hedbergcad718e2013-04-17 15:00:51 +03002928 if (ev->page < HCI_MAX_PAGES)
2929 memcpy(conn->features[ev->page], ev->features, 8);
2930
Johan Hedbergccd556f2010-11-10 17:11:51 +02002931 if (!ev->status && ev->page == 0x01) {
2932 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002933
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002934 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2935 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002936 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002937
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302938 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002939 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302940 } else {
2941 /* It is mandatory by the Bluetooth specification that
2942 * Extended Inquiry Results are only used when Secure
2943 * Simple Pairing is enabled, but some devices violate
2944 * this.
2945 *
2946 * To make these devices work, the internal SSP
2947 * enabled flag needs to be cleared if the remote host
2948 * features do not indicate SSP support */
2949 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2950 }
Marcel Holtmanneb9a8f32014-01-15 22:37:38 -08002951
2952 if (ev->features[0] & LMP_HOST_SC)
2953 set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002954 }
2955
Johan Hedbergccd556f2010-11-10 17:11:51 +02002956 if (conn->state != BT_CONFIG)
2957 goto unlock;
2958
Johan Hedberg671267b2012-05-12 16:11:50 -03002959 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002960 struct hci_cp_remote_name_req cp;
2961 memset(&cp, 0, sizeof(cp));
2962 bacpy(&cp.bdaddr, &conn->dst);
2963 cp.pscan_rep_mode = 0x02;
2964 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002965 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2966 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002967 conn->dst_type, 0, NULL, 0,
2968 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002969
Johan Hedberg127178d2010-11-18 22:22:29 +02002970 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002971 conn->state = BT_CONNECTED;
2972 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002973 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002974 }
2975
2976unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002977 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002978}
2979
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002980static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2981 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002982{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002983 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2984 struct hci_conn *conn;
2985
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002986 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002987
2988 hci_dev_lock(hdev);
2989
2990 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002991 if (!conn) {
2992 if (ev->link_type == ESCO_LINK)
2993 goto unlock;
2994
2995 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2996 if (!conn)
2997 goto unlock;
2998
2999 conn->type = SCO_LINK;
3000 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003001
Marcel Holtmann732547f2009-04-19 19:14:14 +02003002 switch (ev->status) {
3003 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003004 conn->handle = __le16_to_cpu(ev->handle);
3005 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02003006
3007 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02003008 break;
3009
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02003010 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05003011 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003012 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08003013 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003014 case 0x1f: /* Unspecified error */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003015 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02003016 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
3017 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003018 if (hci_setup_sync(conn, conn->link->handle))
3019 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003020 }
3021 /* fall through */
3022
3023 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003024 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003025 break;
3026 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003027
3028 hci_proto_connect_cfm(conn, ev->status);
3029 if (ev->status)
3030 hci_conn_del(conn);
3031
3032unlock:
3033 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003034}
3035
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07003036static inline size_t eir_get_length(u8 *eir, size_t eir_len)
3037{
3038 size_t parsed = 0;
3039
3040 while (parsed < eir_len) {
3041 u8 field_len = eir[0];
3042
3043 if (field_len == 0)
3044 return parsed;
3045
3046 parsed += field_len + 1;
3047 eir += field_len + 1;
3048 }
3049
3050 return eir_len;
3051}
3052
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003053static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3054 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003055{
3056 struct inquiry_data data;
3057 struct extended_inquiry_info *info = (void *) (skb->data + 1);
3058 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303059 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003060
3061 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3062
3063 if (!num_rsp)
3064 return;
3065
Andre Guedes1519cc12012-03-21 00:03:38 -03003066 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3067 return;
3068
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003069 hci_dev_lock(hdev);
3070
Johan Hedberge17acd42011-03-30 23:57:16 +03003071 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003072 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003073
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003074 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003075 data.pscan_rep_mode = info->pscan_rep_mode;
3076 data.pscan_period_mode = info->pscan_period_mode;
3077 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003078 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003079 data.clock_offset = info->clock_offset;
3080 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003081 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003082
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003083 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003084 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003085 sizeof(info->data),
3086 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003087 else
3088 name_known = true;
3089
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003090 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003091 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303092 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003093 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003094 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303095 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003096 }
3097
3098 hci_dev_unlock(hdev);
3099}
3100
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003101static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3102 struct sk_buff *skb)
3103{
3104 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3105 struct hci_conn *conn;
3106
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003107 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003108 __le16_to_cpu(ev->handle));
3109
3110 hci_dev_lock(hdev);
3111
3112 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3113 if (!conn)
3114 goto unlock;
3115
3116 if (!ev->status)
3117 conn->sec_level = conn->pending_sec_level;
3118
3119 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3120
3121 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003122 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003123 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003124 goto unlock;
3125 }
3126
3127 if (conn->state == BT_CONFIG) {
3128 if (!ev->status)
3129 conn->state = BT_CONNECTED;
3130
3131 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003132 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003133 } else {
3134 hci_auth_cfm(conn, ev->status);
3135
3136 hci_conn_hold(conn);
3137 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003138 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003139 }
3140
3141unlock:
3142 hci_dev_unlock(hdev);
3143}
3144
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003145static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003146{
3147 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003148 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3149 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003150 /* If both remote and local IO capabilities allow MITM
3151 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003152 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3153 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3154 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003155 else
Mikel Astizacabae92013-06-28 10:56:28 +02003156 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003157 }
3158
3159 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003160 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3161 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003162 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003163
3164 return conn->auth_type;
3165}
3166
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003167static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003168{
3169 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3170 struct hci_conn *conn;
3171
3172 BT_DBG("%s", hdev->name);
3173
3174 hci_dev_lock(hdev);
3175
3176 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003177 if (!conn)
3178 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003179
Johan Hedberg03b555e2011-01-04 15:40:05 +02003180 hci_conn_hold(conn);
3181
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003182 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003183 goto unlock;
3184
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003185 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003186 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003187 struct hci_cp_io_capability_reply cp;
3188
3189 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303190 /* Change the IO capability from KeyboardDisplay
3191 * to DisplayYesNo as it is not supported by BT spec. */
3192 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003193 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003194 conn->auth_type = hci_get_auth_req(conn);
3195 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003196
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003197 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3198 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003199 cp.oob_data = 0x01;
3200 else
3201 cp.oob_data = 0x00;
3202
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003203 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003204 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003205 } else {
3206 struct hci_cp_io_capability_neg_reply cp;
3207
3208 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003209 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003210
3211 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003212 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003213 }
3214
3215unlock:
3216 hci_dev_unlock(hdev);
3217}
3218
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003219static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003220{
3221 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3222 struct hci_conn *conn;
3223
3224 BT_DBG("%s", hdev->name);
3225
3226 hci_dev_lock(hdev);
3227
3228 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3229 if (!conn)
3230 goto unlock;
3231
Johan Hedberg03b555e2011-01-04 15:40:05 +02003232 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003233 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003234 if (ev->oob_data)
3235 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003236
3237unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003238 hci_dev_unlock(hdev);
3239}
3240
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003241static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3242 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003243{
3244 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003245 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003246 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003247
3248 BT_DBG("%s", hdev->name);
3249
3250 hci_dev_lock(hdev);
3251
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003252 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003253 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003254
Johan Hedberg7a828902011-04-28 11:28:53 -07003255 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3256 if (!conn)
3257 goto unlock;
3258
3259 loc_mitm = (conn->auth_type & 0x01);
3260 rem_mitm = (conn->remote_auth & 0x01);
3261
3262 /* If we require MITM but the remote device can't provide that
3263 * (it has NoInputNoOutput) then reject the confirmation
3264 * request. The only exception is when we're dedicated bonding
3265 * initiators (connect_cfm_cb set) since then we always have the MITM
3266 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003267 if (!conn->connect_cfm_cb && loc_mitm &&
3268 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003269 BT_DBG("Rejecting request: remote device can't provide MITM");
3270 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003271 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003272 goto unlock;
3273 }
3274
3275 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003276 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3277 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003278
3279 /* If we're not the initiators request authorization to
3280 * proceed from user space (mgmt_user_confirm with
3281 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003282 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003283 BT_DBG("Confirming auto-accept as acceptor");
3284 confirm_hint = 1;
3285 goto confirm;
3286 }
3287
Johan Hedberg9f616562011-04-28 11:28:54 -07003288 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003289 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003290
3291 if (hdev->auto_accept_delay > 0) {
3292 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
Johan Hedberg7bc18d92013-10-16 18:11:39 +03003293 queue_delayed_work(conn->hdev->workqueue,
3294 &conn->auto_accept_work, delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003295 goto unlock;
3296 }
3297
Johan Hedberg7a828902011-04-28 11:28:53 -07003298 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003299 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003300 goto unlock;
3301 }
3302
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003303confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003304 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003305 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003306
3307unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003308 hci_dev_unlock(hdev);
3309}
3310
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003311static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3312 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003313{
3314 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3315
3316 BT_DBG("%s", hdev->name);
3317
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003318 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003319 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003320}
3321
Johan Hedberg92a25252012-09-06 18:39:26 +03003322static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3323 struct sk_buff *skb)
3324{
3325 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3326 struct hci_conn *conn;
3327
3328 BT_DBG("%s", hdev->name);
3329
3330 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3331 if (!conn)
3332 return;
3333
3334 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3335 conn->passkey_entered = 0;
3336
3337 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3338 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3339 conn->dst_type, conn->passkey_notify,
3340 conn->passkey_entered);
3341}
3342
3343static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3344{
3345 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3346 struct hci_conn *conn;
3347
3348 BT_DBG("%s", hdev->name);
3349
3350 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3351 if (!conn)
3352 return;
3353
3354 switch (ev->type) {
3355 case HCI_KEYPRESS_STARTED:
3356 conn->passkey_entered = 0;
3357 return;
3358
3359 case HCI_KEYPRESS_ENTERED:
3360 conn->passkey_entered++;
3361 break;
3362
3363 case HCI_KEYPRESS_ERASED:
3364 conn->passkey_entered--;
3365 break;
3366
3367 case HCI_KEYPRESS_CLEARED:
3368 conn->passkey_entered = 0;
3369 break;
3370
3371 case HCI_KEYPRESS_COMPLETED:
3372 return;
3373 }
3374
3375 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3376 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3377 conn->dst_type, conn->passkey_notify,
3378 conn->passkey_entered);
3379}
3380
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003381static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3382 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003383{
3384 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3385 struct hci_conn *conn;
3386
3387 BT_DBG("%s", hdev->name);
3388
3389 hci_dev_lock(hdev);
3390
3391 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003392 if (!conn)
3393 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003394
Johan Hedberg2a611692011-02-19 12:06:00 -03003395 /* To avoid duplicate auth_failed events to user space we check
3396 * the HCI_CONN_AUTH_PEND flag which will be set if we
3397 * initiated the authentication. A traditional auth_complete
3398 * event gets always produced as initiator and is also mapped to
3399 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003400 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003401 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003402 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003403
David Herrmann76a68ba2013-04-06 20:28:37 +02003404 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003405
3406unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003407 hci_dev_unlock(hdev);
3408}
3409
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003410static void hci_remote_host_features_evt(struct hci_dev *hdev,
3411 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003412{
3413 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3414 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003415 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003416
3417 BT_DBG("%s", hdev->name);
3418
3419 hci_dev_lock(hdev);
3420
Johan Hedbergcad718e2013-04-17 15:00:51 +03003421 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3422 if (conn)
3423 memcpy(conn->features[1], ev->features, 8);
3424
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003425 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3426 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003427 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003428
3429 hci_dev_unlock(hdev);
3430}
3431
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003432static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3433 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003434{
3435 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3436 struct oob_data *data;
3437
3438 BT_DBG("%s", hdev->name);
3439
3440 hci_dev_lock(hdev);
3441
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003442 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003443 goto unlock;
3444
Szymon Janc2763eda2011-03-22 13:12:22 +01003445 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3446 if (data) {
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003447 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
3448 struct hci_cp_remote_oob_ext_data_reply cp;
Szymon Janc2763eda2011-03-22 13:12:22 +01003449
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003450 bacpy(&cp.bdaddr, &ev->bdaddr);
3451 memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
3452 memcpy(cp.randomizer192, data->randomizer192,
3453 sizeof(cp.randomizer192));
3454 memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
3455 memcpy(cp.randomizer256, data->randomizer256,
3456 sizeof(cp.randomizer256));
Szymon Janc2763eda2011-03-22 13:12:22 +01003457
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003458 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
3459 sizeof(cp), &cp);
3460 } else {
3461 struct hci_cp_remote_oob_data_reply cp;
3462
3463 bacpy(&cp.bdaddr, &ev->bdaddr);
3464 memcpy(cp.hash, data->hash192, sizeof(cp.hash));
3465 memcpy(cp.randomizer, data->randomizer192,
3466 sizeof(cp.randomizer));
3467
3468 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
3469 sizeof(cp), &cp);
3470 }
Szymon Janc2763eda2011-03-22 13:12:22 +01003471 } else {
3472 struct hci_cp_remote_oob_data_neg_reply cp;
3473
3474 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003475 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
3476 sizeof(cp), &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003477 }
3478
Szymon Jance1ba1f12011-04-06 13:01:59 +02003479unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003480 hci_dev_unlock(hdev);
3481}
3482
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003483static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3484 struct sk_buff *skb)
3485{
3486 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3487 struct hci_conn *hcon, *bredr_hcon;
3488
3489 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3490 ev->status);
3491
3492 hci_dev_lock(hdev);
3493
3494 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3495 if (!hcon) {
3496 hci_dev_unlock(hdev);
3497 return;
3498 }
3499
3500 if (ev->status) {
3501 hci_conn_del(hcon);
3502 hci_dev_unlock(hdev);
3503 return;
3504 }
3505
3506 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3507
3508 hcon->state = BT_CONNECTED;
3509 bacpy(&hcon->dst, &bredr_hcon->dst);
3510
3511 hci_conn_hold(hcon);
3512 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003513 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003514
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003515 hci_conn_add_sysfs(hcon);
3516
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003517 amp_physical_cfm(bredr_hcon, hcon);
3518
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003519 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003520}
3521
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003522static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3523{
3524 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3525 struct hci_conn *hcon;
3526 struct hci_chan *hchan;
3527 struct amp_mgr *mgr;
3528
3529 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3530 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3531 ev->status);
3532
3533 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3534 if (!hcon)
3535 return;
3536
3537 /* Create AMP hchan */
3538 hchan = hci_chan_create(hcon);
3539 if (!hchan)
3540 return;
3541
3542 hchan->handle = le16_to_cpu(ev->handle);
3543
3544 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3545
3546 mgr = hcon->amp_mgr;
3547 if (mgr && mgr->bredr_chan) {
3548 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3549
3550 l2cap_chan_lock(bredr_chan);
3551
3552 bredr_chan->conn->mtu = hdev->block_mtu;
3553 l2cap_logical_cfm(bredr_chan, hchan, 0);
3554 hci_conn_hold(hcon);
3555
3556 l2cap_chan_unlock(bredr_chan);
3557 }
3558}
3559
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003560static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3561 struct sk_buff *skb)
3562{
3563 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3564 struct hci_chan *hchan;
3565
3566 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3567 le16_to_cpu(ev->handle), ev->status);
3568
3569 if (ev->status)
3570 return;
3571
3572 hci_dev_lock(hdev);
3573
3574 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3575 if (!hchan)
3576 goto unlock;
3577
3578 amp_destroy_logical_link(hchan, ev->reason);
3579
3580unlock:
3581 hci_dev_unlock(hdev);
3582}
3583
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003584static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3585 struct sk_buff *skb)
3586{
3587 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3588 struct hci_conn *hcon;
3589
3590 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3591
3592 if (ev->status)
3593 return;
3594
3595 hci_dev_lock(hdev);
3596
3597 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3598 if (hcon) {
3599 hcon->state = BT_CLOSED;
3600 hci_conn_del(hcon);
3601 }
3602
3603 hci_dev_unlock(hdev);
3604}
3605
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003606static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003607{
3608 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3609 struct hci_conn *conn;
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003610 struct smp_irk *irk;
Ville Tervofcd89c02011-02-10 22:38:47 -03003611
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003612 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003613
3614 hci_dev_lock(hdev);
3615
Andre Guedesb47a09b2012-07-27 15:10:15 -03003616 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003617 if (!conn) {
3618 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3619 if (!conn) {
3620 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003621 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003622 }
Andre Guedes29b79882011-05-31 14:20:54 -03003623
3624 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003625
Marcel Holtmann880be4e2013-10-13 07:25:18 -07003626 /* The advertising parameters for own address type
3627 * define which source address and source address
3628 * type this connections has.
3629 */
3630 if (bacmp(&conn->src, BDADDR_ANY)) {
3631 conn->src_type = ADDR_LE_DEV_PUBLIC;
3632 } else {
3633 bacpy(&conn->src, &hdev->static_addr);
3634 conn->src_type = ADDR_LE_DEV_RANDOM;
3635 }
3636
Andre Guedesb9b343d2012-07-27 15:10:11 -03003637 if (ev->role == LE_CONN_ROLE_MASTER) {
3638 conn->out = true;
3639 conn->link_mode |= HCI_LM_MASTER;
3640 }
Ville Tervob62f3282011-02-10 22:38:50 -03003641 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003642
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003643 /* Ensure that the hci_conn contains the identity address type
3644 * regardless of which address the connection was made with.
3645 *
3646 * If the controller has a public BD_ADDR, then by default
3647 * use that one. If this is a LE only controller without
3648 * a public address, default to the static random address.
3649 *
3650 * For debugging purposes it is possible to force
3651 * controllers with a public address to use the static
3652 * random address instead.
3653 */
3654 if (test_bit(HCI_FORCE_STATIC_ADDR, &hdev->dev_flags) ||
3655 !bacmp(&hdev->bdaddr, BDADDR_ANY)) {
3656 bacpy(&conn->src, &hdev->static_addr);
3657 conn->src_type = ADDR_LE_DEV_RANDOM;
3658 } else {
3659 bacpy(&conn->src, &hdev->bdaddr);
3660 conn->src_type = ADDR_LE_DEV_PUBLIC;
3661 }
3662
Marcel Holtmannedb4b462014-02-18 15:13:43 -08003663 /* Lookup the identity address from the stored connection
3664 * address and address type.
3665 *
3666 * When establishing connections to an identity address, the
3667 * connection procedure will store the resolvable random
3668 * address first. Now if it can be converted back into the
3669 * identity address, start using the identity address from
3670 * now on.
3671 */
3672 irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003673 if (irk) {
3674 bacpy(&conn->dst, &irk->bdaddr);
3675 conn->dst_type = irk->addr_type;
3676 }
3677
Andre Guedescd17dec2012-07-27 15:10:16 -03003678 if (ev->status) {
Andre Guedes06c053f2014-02-26 20:21:41 -03003679 hci_le_conn_failed(conn, ev->status);
Andre Guedescd17dec2012-07-27 15:10:16 -03003680 goto unlock;
3681 }
3682
Johan Hedbergb644ba32012-01-17 21:48:47 +02003683 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Marcel Holtmann01fdb0f2014-02-18 14:22:19 -08003684 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003685 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003686
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003687 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003688 conn->handle = __le16_to_cpu(ev->handle);
3689 conn->state = BT_CONNECTED;
3690
Jukka Rissanen18722c22013-12-11 17:05:37 +02003691 if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
3692 set_bit(HCI_CONN_6LOWPAN, &conn->flags);
3693
Ville Tervofcd89c02011-02-10 22:38:47 -03003694 hci_conn_add_sysfs(conn);
3695
3696 hci_proto_connect_cfm(conn, ev->status);
3697
Andre Guedesa4790db2014-02-26 20:21:47 -03003698 hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type);
3699
Ville Tervofcd89c02011-02-10 22:38:47 -03003700unlock:
3701 hci_dev_unlock(hdev);
3702}
3703
Andre Guedesa4790db2014-02-26 20:21:47 -03003704/* This function requires the caller holds hdev->lock */
3705static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
3706 u8 addr_type)
3707{
3708 struct hci_conn *conn;
3709
3710 if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
3711 return;
3712
3713 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
3714 HCI_AT_NO_BONDING);
3715 if (!IS_ERR(conn))
3716 return;
3717
3718 switch (PTR_ERR(conn)) {
3719 case -EBUSY:
3720 /* If hci_connect() returns -EBUSY it means there is already
3721 * an LE connection attempt going on. Since controllers don't
3722 * support more than one connection attempt at the time, we
3723 * don't consider this an error case.
3724 */
3725 break;
3726 default:
3727 BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
3728 }
3729}
3730
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003731static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003732{
Andre Guedese95beb42011-09-26 20:48:35 -03003733 u8 num_reports = skb->data[0];
3734 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003735 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003736
Andre Guedesa4790db2014-02-26 20:21:47 -03003737 hci_dev_lock(hdev);
3738
Andre Guedese95beb42011-09-26 20:48:35 -03003739 while (num_reports--) {
3740 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003741
Andre Guedesa4790db2014-02-26 20:21:47 -03003742 if (ev->evt_type == LE_ADV_IND ||
3743 ev->evt_type == LE_ADV_DIRECT_IND)
3744 check_pending_le_conn(hdev, &ev->bdaddr,
3745 ev->bdaddr_type);
3746
Andre Guedes3c9e9192012-01-10 18:20:50 -03003747 rssi = ev->data[ev->length];
3748 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003749 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003750
Andre Guedese95beb42011-09-26 20:48:35 -03003751 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003752 }
Andre Guedesa4790db2014-02-26 20:21:47 -03003753
3754 hci_dev_unlock(hdev);
Andre Guedes9aa04c92011-05-26 16:23:51 -03003755}
3756
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003757static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003758{
3759 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3760 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003761 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003762 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003763 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003764
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003765 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003766
3767 hci_dev_lock(hdev);
3768
3769 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003770 if (conn == NULL)
3771 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003772
Johan Hedberg98a0b842014-01-30 19:40:00 -08003773 ltk = hci_find_ltk(hdev, ev->ediv, ev->random, conn->out);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003774 if (ltk == NULL)
3775 goto not_found;
3776
3777 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003778 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003779
3780 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03003781 conn->pending_sec_level = BT_SECURITY_HIGH;
3782 else
3783 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003784
Andre Guedes89cbb4d2013-07-31 16:25:29 -03003785 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003786
3787 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3788
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003789 if (ltk->type & HCI_SMP_STK) {
3790 list_del(&ltk->list);
3791 kfree(ltk);
3792 }
3793
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003794 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003795
3796 return;
3797
3798not_found:
3799 neg.handle = ev->handle;
3800 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3801 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003802}
3803
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003804static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003805{
3806 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3807
3808 skb_pull(skb, sizeof(*le_ev));
3809
3810 switch (le_ev->subevent) {
3811 case HCI_EV_LE_CONN_COMPLETE:
3812 hci_le_conn_complete_evt(hdev, skb);
3813 break;
3814
Andre Guedes9aa04c92011-05-26 16:23:51 -03003815 case HCI_EV_LE_ADVERTISING_REPORT:
3816 hci_le_adv_report_evt(hdev, skb);
3817 break;
3818
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003819 case HCI_EV_LE_LTK_REQ:
3820 hci_le_ltk_request_evt(hdev, skb);
3821 break;
3822
Ville Tervofcd89c02011-02-10 22:38:47 -03003823 default:
3824 break;
3825 }
3826}
3827
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003828static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3829{
3830 struct hci_ev_channel_selected *ev = (void *) skb->data;
3831 struct hci_conn *hcon;
3832
3833 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3834
3835 skb_pull(skb, sizeof(*ev));
3836
3837 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3838 if (!hcon)
3839 return;
3840
3841 amp_read_loc_assoc_final_data(hdev, hcon);
3842}
3843
Linus Torvalds1da177e2005-04-16 15:20:36 -07003844void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3845{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003846 struct hci_event_hdr *hdr = (void *) skb->data;
3847 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003848
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003849 hci_dev_lock(hdev);
3850
3851 /* Received events are (currently) only needed when a request is
3852 * ongoing so avoid unnecessary memory allocation.
3853 */
3854 if (hdev->req_status == HCI_REQ_PEND) {
3855 kfree_skb(hdev->recv_evt);
3856 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3857 }
3858
3859 hci_dev_unlock(hdev);
3860
Linus Torvalds1da177e2005-04-16 15:20:36 -07003861 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3862
Johan Hedberg02350a72013-04-03 21:50:29 +03003863 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02003864 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
3865 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03003866
3867 hci_req_cmd_complete(hdev, opcode, 0);
3868 }
3869
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003870 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003871 case HCI_EV_INQUIRY_COMPLETE:
3872 hci_inquiry_complete_evt(hdev, skb);
3873 break;
3874
3875 case HCI_EV_INQUIRY_RESULT:
3876 hci_inquiry_result_evt(hdev, skb);
3877 break;
3878
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003879 case HCI_EV_CONN_COMPLETE:
3880 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003881 break;
3882
Linus Torvalds1da177e2005-04-16 15:20:36 -07003883 case HCI_EV_CONN_REQUEST:
3884 hci_conn_request_evt(hdev, skb);
3885 break;
3886
Linus Torvalds1da177e2005-04-16 15:20:36 -07003887 case HCI_EV_DISCONN_COMPLETE:
3888 hci_disconn_complete_evt(hdev, skb);
3889 break;
3890
Linus Torvalds1da177e2005-04-16 15:20:36 -07003891 case HCI_EV_AUTH_COMPLETE:
3892 hci_auth_complete_evt(hdev, skb);
3893 break;
3894
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003895 case HCI_EV_REMOTE_NAME:
3896 hci_remote_name_evt(hdev, skb);
3897 break;
3898
Linus Torvalds1da177e2005-04-16 15:20:36 -07003899 case HCI_EV_ENCRYPT_CHANGE:
3900 hci_encrypt_change_evt(hdev, skb);
3901 break;
3902
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003903 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3904 hci_change_link_key_complete_evt(hdev, skb);
3905 break;
3906
3907 case HCI_EV_REMOTE_FEATURES:
3908 hci_remote_features_evt(hdev, skb);
3909 break;
3910
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003911 case HCI_EV_CMD_COMPLETE:
3912 hci_cmd_complete_evt(hdev, skb);
3913 break;
3914
3915 case HCI_EV_CMD_STATUS:
3916 hci_cmd_status_evt(hdev, skb);
3917 break;
3918
3919 case HCI_EV_ROLE_CHANGE:
3920 hci_role_change_evt(hdev, skb);
3921 break;
3922
3923 case HCI_EV_NUM_COMP_PKTS:
3924 hci_num_comp_pkts_evt(hdev, skb);
3925 break;
3926
3927 case HCI_EV_MODE_CHANGE:
3928 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003929 break;
3930
3931 case HCI_EV_PIN_CODE_REQ:
3932 hci_pin_code_request_evt(hdev, skb);
3933 break;
3934
3935 case HCI_EV_LINK_KEY_REQ:
3936 hci_link_key_request_evt(hdev, skb);
3937 break;
3938
3939 case HCI_EV_LINK_KEY_NOTIFY:
3940 hci_link_key_notify_evt(hdev, skb);
3941 break;
3942
3943 case HCI_EV_CLOCK_OFFSET:
3944 hci_clock_offset_evt(hdev, skb);
3945 break;
3946
Marcel Holtmanna8746412008-07-14 20:13:46 +02003947 case HCI_EV_PKT_TYPE_CHANGE:
3948 hci_pkt_type_change_evt(hdev, skb);
3949 break;
3950
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003951 case HCI_EV_PSCAN_REP_MODE:
3952 hci_pscan_rep_mode_evt(hdev, skb);
3953 break;
3954
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003955 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3956 hci_inquiry_result_with_rssi_evt(hdev, skb);
3957 break;
3958
3959 case HCI_EV_REMOTE_EXT_FEATURES:
3960 hci_remote_ext_features_evt(hdev, skb);
3961 break;
3962
3963 case HCI_EV_SYNC_CONN_COMPLETE:
3964 hci_sync_conn_complete_evt(hdev, skb);
3965 break;
3966
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003967 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3968 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003969 break;
3970
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003971 case HCI_EV_KEY_REFRESH_COMPLETE:
3972 hci_key_refresh_complete_evt(hdev, skb);
3973 break;
3974
Marcel Holtmann04936842008-07-14 20:13:48 +02003975 case HCI_EV_IO_CAPA_REQUEST:
3976 hci_io_capa_request_evt(hdev, skb);
3977 break;
3978
Johan Hedberg03b555e2011-01-04 15:40:05 +02003979 case HCI_EV_IO_CAPA_REPLY:
3980 hci_io_capa_reply_evt(hdev, skb);
3981 break;
3982
Johan Hedberga5c29682011-02-19 12:05:57 -03003983 case HCI_EV_USER_CONFIRM_REQUEST:
3984 hci_user_confirm_request_evt(hdev, skb);
3985 break;
3986
Brian Gix1143d452011-11-23 08:28:34 -08003987 case HCI_EV_USER_PASSKEY_REQUEST:
3988 hci_user_passkey_request_evt(hdev, skb);
3989 break;
3990
Johan Hedberg92a25252012-09-06 18:39:26 +03003991 case HCI_EV_USER_PASSKEY_NOTIFY:
3992 hci_user_passkey_notify_evt(hdev, skb);
3993 break;
3994
3995 case HCI_EV_KEYPRESS_NOTIFY:
3996 hci_keypress_notify_evt(hdev, skb);
3997 break;
3998
Marcel Holtmann04936842008-07-14 20:13:48 +02003999 case HCI_EV_SIMPLE_PAIR_COMPLETE:
4000 hci_simple_pair_complete_evt(hdev, skb);
4001 break;
4002
Marcel Holtmann41a96212008-07-14 20:13:48 +02004003 case HCI_EV_REMOTE_HOST_FEATURES:
4004 hci_remote_host_features_evt(hdev, skb);
4005 break;
4006
Ville Tervofcd89c02011-02-10 22:38:47 -03004007 case HCI_EV_LE_META:
4008 hci_le_meta_evt(hdev, skb);
4009 break;
4010
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004011 case HCI_EV_CHANNEL_SELECTED:
4012 hci_chan_selected_evt(hdev, skb);
4013 break;
4014
Szymon Janc2763eda2011-03-22 13:12:22 +01004015 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
4016 hci_remote_oob_data_request_evt(hdev, skb);
4017 break;
4018
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03004019 case HCI_EV_PHY_LINK_COMPLETE:
4020 hci_phy_link_complete_evt(hdev, skb);
4021 break;
4022
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004023 case HCI_EV_LOGICAL_LINK_COMPLETE:
4024 hci_loglink_complete_evt(hdev, skb);
4025 break;
4026
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02004027 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
4028 hci_disconn_loglink_complete_evt(hdev, skb);
4029 break;
4030
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02004031 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
4032 hci_disconn_phylink_complete_evt(hdev, skb);
4033 break;
4034
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02004035 case HCI_EV_NUM_COMP_BLOCKS:
4036 hci_num_comp_blocks_evt(hdev, skb);
4037 break;
4038
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004039 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03004040 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004041 break;
4042 }
4043
4044 kfree_skb(skb);
4045 hdev->stat.evt_rx++;
4046}