blob: 162235633bf5f1c4a46e73f8b433285796a18ffe [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
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02001081static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
1082{
1083 struct hci_cp_le_set_adv_param *cp;
1084 u8 status = *((u8 *) skb->data);
1085
1086 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1087
1088 if (status)
1089 return;
1090
1091 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM);
1092 if (!cp)
1093 return;
1094
1095 hci_dev_lock(hdev);
1096 hdev->adv_addr_type = cp->own_address_type;
1097 hci_dev_unlock(hdev);
1098}
1099
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001100static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1101 struct sk_buff *skb)
1102{
1103 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1104
1105 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1106 hdev->name, rp->status, rp->phy_handle);
1107
1108 if (rp->status)
1109 return;
1110
1111 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1112}
1113
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001114static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001115{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001116 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001117
1118 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001119 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001120 return;
1121 }
1122
Andre Guedes89352e72011-11-04 14:16:53 -03001123 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001124}
1125
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001126static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001128 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001131 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001132
1133 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 if (!cp)
1135 return;
1136
1137 hci_dev_lock(hdev);
1138
1139 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1140
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001141 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142
1143 if (status) {
1144 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001145 if (status != 0x0c || conn->attempt > 2) {
1146 conn->state = BT_CLOSED;
1147 hci_proto_connect_cfm(conn, status);
1148 hci_conn_del(conn);
1149 } else
1150 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 }
1152 } else {
1153 if (!conn) {
1154 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1155 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001156 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 conn->link_mode |= HCI_LM_MASTER;
1158 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001159 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 }
1161 }
1162
1163 hci_dev_unlock(hdev);
1164}
1165
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001166static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001168 struct hci_cp_add_sco *cp;
1169 struct hci_conn *acl, *sco;
1170 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001172 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001173
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001174 if (!status)
1175 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001177 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1178 if (!cp)
1179 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001181 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001183 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001184
1185 hci_dev_lock(hdev);
1186
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001187 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001188 if (acl) {
1189 sco = acl->link;
1190 if (sco) {
1191 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001192
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001193 hci_proto_connect_cfm(sco, status);
1194 hci_conn_del(sco);
1195 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001196 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001197
1198 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199}
1200
Marcel Holtmannf8558552008-07-14 20:13:49 +02001201static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1202{
1203 struct hci_cp_auth_requested *cp;
1204 struct hci_conn *conn;
1205
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001206 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001207
1208 if (!status)
1209 return;
1210
1211 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1212 if (!cp)
1213 return;
1214
1215 hci_dev_lock(hdev);
1216
1217 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1218 if (conn) {
1219 if (conn->state == BT_CONFIG) {
1220 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001221 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001222 }
1223 }
1224
1225 hci_dev_unlock(hdev);
1226}
1227
1228static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1229{
1230 struct hci_cp_set_conn_encrypt *cp;
1231 struct hci_conn *conn;
1232
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001233 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001234
1235 if (!status)
1236 return;
1237
1238 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1239 if (!cp)
1240 return;
1241
1242 hci_dev_lock(hdev);
1243
1244 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1245 if (conn) {
1246 if (conn->state == BT_CONFIG) {
1247 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001248 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001249 }
1250 }
1251
1252 hci_dev_unlock(hdev);
1253}
1254
Johan Hedberg127178d2010-11-18 22:22:29 +02001255static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001256 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001257{
Johan Hedberg392599b2010-11-18 22:22:28 +02001258 if (conn->state != BT_CONFIG || !conn->out)
1259 return 0;
1260
Johan Hedberg765c2a92011-01-19 12:06:52 +05301261 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001262 return 0;
1263
1264 /* Only request authentication for SSP connections or non-SSP
Johan Hedberg264b8b42014-01-08 16:40:39 +02001265 * devices with sec_level MEDIUM or HIGH or if MITM protection
1266 * is requested.
1267 */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001268 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
Johan Hedberg264b8b42014-01-08 16:40:39 +02001269 conn->pending_sec_level != BT_SECURITY_HIGH &&
1270 conn->pending_sec_level != BT_SECURITY_MEDIUM)
Johan Hedberg392599b2010-11-18 22:22:28 +02001271 return 0;
1272
Johan Hedberg392599b2010-11-18 22:22:28 +02001273 return 1;
1274}
1275
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001276static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001277 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001278{
1279 struct hci_cp_remote_name_req cp;
1280
1281 memset(&cp, 0, sizeof(cp));
1282
1283 bacpy(&cp.bdaddr, &e->data.bdaddr);
1284 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1285 cp.pscan_mode = e->data.pscan_mode;
1286 cp.clock_offset = e->data.clock_offset;
1287
1288 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1289}
1290
Johan Hedbergb644ba32012-01-17 21:48:47 +02001291static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001292{
1293 struct discovery_state *discov = &hdev->discovery;
1294 struct inquiry_entry *e;
1295
Johan Hedbergb644ba32012-01-17 21:48:47 +02001296 if (list_empty(&discov->resolve))
1297 return false;
1298
1299 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001300 if (!e)
1301 return false;
1302
Johan Hedbergb644ba32012-01-17 21:48:47 +02001303 if (hci_resolve_name(hdev, e) == 0) {
1304 e->name_state = NAME_PENDING;
1305 return true;
1306 }
1307
1308 return false;
1309}
1310
1311static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001312 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001313{
1314 struct discovery_state *discov = &hdev->discovery;
1315 struct inquiry_entry *e;
1316
1317 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001318 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1319 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001320
1321 if (discov->state == DISCOVERY_STOPPED)
1322 return;
1323
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001324 if (discov->state == DISCOVERY_STOPPING)
1325 goto discov_complete;
1326
1327 if (discov->state != DISCOVERY_RESOLVING)
1328 return;
1329
1330 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001331 /* If the device was not found in a list of found devices names of which
1332 * are pending. there is no need to continue resolving a next name as it
1333 * will be done upon receiving another Remote Name Request Complete
1334 * Event */
1335 if (!e)
1336 return;
1337
1338 list_del(&e->list);
1339 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001340 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001341 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1342 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001343 } else {
1344 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001345 }
1346
Johan Hedbergb644ba32012-01-17 21:48:47 +02001347 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001348 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001349
1350discov_complete:
1351 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1352}
1353
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001354static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1355{
Johan Hedberg127178d2010-11-18 22:22:29 +02001356 struct hci_cp_remote_name_req *cp;
1357 struct hci_conn *conn;
1358
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001359 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001360
1361 /* If successful wait for the name req complete event before
1362 * checking for the need to do authentication */
1363 if (!status)
1364 return;
1365
1366 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1367 if (!cp)
1368 return;
1369
1370 hci_dev_lock(hdev);
1371
1372 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001373
1374 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1375 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1376
Johan Hedberg79c6c702011-04-28 11:28:55 -07001377 if (!conn)
1378 goto unlock;
1379
1380 if (!hci_outgoing_auth_needed(hdev, conn))
1381 goto unlock;
1382
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001383 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001384 struct hci_cp_auth_requested auth_cp;
1385
1386 auth_cp.handle = __cpu_to_le16(conn->handle);
1387 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1388 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001389 }
1390
Johan Hedberg79c6c702011-04-28 11:28:55 -07001391unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001392 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001393}
1394
Marcel Holtmann769be972008-07-14 20:13:49 +02001395static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1396{
1397 struct hci_cp_read_remote_features *cp;
1398 struct hci_conn *conn;
1399
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001400 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001401
1402 if (!status)
1403 return;
1404
1405 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1406 if (!cp)
1407 return;
1408
1409 hci_dev_lock(hdev);
1410
1411 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1412 if (conn) {
1413 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001414 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001415 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001416 }
1417 }
1418
1419 hci_dev_unlock(hdev);
1420}
1421
1422static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1423{
1424 struct hci_cp_read_remote_ext_features *cp;
1425 struct hci_conn *conn;
1426
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001427 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001428
1429 if (!status)
1430 return;
1431
1432 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1433 if (!cp)
1434 return;
1435
1436 hci_dev_lock(hdev);
1437
1438 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1439 if (conn) {
1440 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001441 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001442 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001443 }
1444 }
1445
1446 hci_dev_unlock(hdev);
1447}
1448
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001449static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1450{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001451 struct hci_cp_setup_sync_conn *cp;
1452 struct hci_conn *acl, *sco;
1453 __u16 handle;
1454
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001455 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001456
1457 if (!status)
1458 return;
1459
1460 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1461 if (!cp)
1462 return;
1463
1464 handle = __le16_to_cpu(cp->handle);
1465
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001466 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001467
1468 hci_dev_lock(hdev);
1469
1470 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001471 if (acl) {
1472 sco = acl->link;
1473 if (sco) {
1474 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001475
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001476 hci_proto_connect_cfm(sco, status);
1477 hci_conn_del(sco);
1478 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001479 }
1480
1481 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001482}
1483
1484static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1485{
1486 struct hci_cp_sniff_mode *cp;
1487 struct hci_conn *conn;
1488
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001489 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001490
1491 if (!status)
1492 return;
1493
1494 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1495 if (!cp)
1496 return;
1497
1498 hci_dev_lock(hdev);
1499
1500 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001501 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001502 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001503
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001504 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001505 hci_sco_setup(conn, status);
1506 }
1507
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001508 hci_dev_unlock(hdev);
1509}
1510
1511static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1512{
1513 struct hci_cp_exit_sniff_mode *cp;
1514 struct hci_conn *conn;
1515
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001516 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001517
1518 if (!status)
1519 return;
1520
1521 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1522 if (!cp)
1523 return;
1524
1525 hci_dev_lock(hdev);
1526
1527 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001528 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001529 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001530
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001531 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001532 hci_sco_setup(conn, status);
1533 }
1534
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001535 hci_dev_unlock(hdev);
1536}
1537
Johan Hedberg88c3df12012-02-09 14:27:38 +02001538static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1539{
1540 struct hci_cp_disconnect *cp;
1541 struct hci_conn *conn;
1542
1543 if (!status)
1544 return;
1545
1546 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1547 if (!cp)
1548 return;
1549
1550 hci_dev_lock(hdev);
1551
1552 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1553 if (conn)
1554 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001555 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001556
1557 hci_dev_unlock(hdev);
1558}
1559
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001560static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1561{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001562 struct hci_cp_create_phy_link *cp;
1563
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001564 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001565
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001566 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1567 if (!cp)
1568 return;
1569
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001570 hci_dev_lock(hdev);
1571
1572 if (status) {
1573 struct hci_conn *hcon;
1574
1575 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1576 if (hcon)
1577 hci_conn_del(hcon);
1578 } else {
1579 amp_write_remote_assoc(hdev, cp->phy_handle);
1580 }
1581
1582 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001583}
1584
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001585static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1586{
1587 struct hci_cp_accept_phy_link *cp;
1588
1589 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1590
1591 if (status)
1592 return;
1593
1594 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1595 if (!cp)
1596 return;
1597
1598 amp_write_remote_assoc(hdev, cp->phy_handle);
1599}
1600
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001601static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001602{
1603 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001604 struct discovery_state *discov = &hdev->discovery;
1605 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001606
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001607 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001608
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001609 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001610
1611 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1612 return;
1613
Andre Guedes3e13fa12013-03-27 20:04:56 -03001614 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1615 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1616
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001617 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001618 return;
1619
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001620 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001621
Andre Guedes343f9352012-02-17 20:39:37 -03001622 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001623 goto unlock;
1624
1625 if (list_empty(&discov->resolve)) {
1626 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1627 goto unlock;
1628 }
1629
1630 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1631 if (e && hci_resolve_name(hdev, e) == 0) {
1632 e->name_state = NAME_PENDING;
1633 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1634 } else {
1635 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1636 }
1637
1638unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001639 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001640}
1641
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001642static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001644 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001645 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646 int num_rsp = *((__u8 *) skb->data);
1647
1648 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1649
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001650 if (!num_rsp)
1651 return;
1652
Andre Guedes1519cc12012-03-21 00:03:38 -03001653 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1654 return;
1655
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001657
Johan Hedberge17acd42011-03-30 23:57:16 +03001658 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001659 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001660
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661 bacpy(&data.bdaddr, &info->bdaddr);
1662 data.pscan_rep_mode = info->pscan_rep_mode;
1663 data.pscan_period_mode = info->pscan_period_mode;
1664 data.pscan_mode = info->pscan_mode;
1665 memcpy(data.dev_class, info->dev_class, 3);
1666 data.clock_offset = info->clock_offset;
1667 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001668 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001669
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001670 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001671 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001672 info->dev_class, 0, !name_known, ssp, NULL,
1673 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001675
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 hci_dev_unlock(hdev);
1677}
1678
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001679static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001681 struct hci_ev_conn_complete *ev = (void *) skb->data;
1682 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001684 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001685
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001687
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001688 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001689 if (!conn) {
1690 if (ev->link_type != SCO_LINK)
1691 goto unlock;
1692
1693 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1694 if (!conn)
1695 goto unlock;
1696
1697 conn->type = SCO_LINK;
1698 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001699
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001700 if (!ev->status) {
1701 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001702
1703 if (conn->type == ACL_LINK) {
1704 conn->state = BT_CONFIG;
1705 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001706
1707 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1708 !hci_find_link_key(hdev, &ev->bdaddr))
1709 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1710 else
1711 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001712 } else
1713 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001714
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001715 hci_conn_add_sysfs(conn);
1716
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001717 if (test_bit(HCI_AUTH, &hdev->flags))
1718 conn->link_mode |= HCI_LM_AUTH;
1719
1720 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1721 conn->link_mode |= HCI_LM_ENCRYPT;
1722
1723 /* Get remote features */
1724 if (conn->type == ACL_LINK) {
1725 struct hci_cp_read_remote_features cp;
1726 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001727 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001728 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001729 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001730
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001731 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001732 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001733 struct hci_cp_change_conn_ptype cp;
1734 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001735 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001736 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1737 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001738 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001739 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001740 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001741 if (conn->type == ACL_LINK)
Marcel Holtmann64c7b772014-02-18 14:22:20 -08001742 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001743 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001744 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001745
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001746 if (conn->type == ACL_LINK)
1747 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001748
Marcel Holtmann769be972008-07-14 20:13:49 +02001749 if (ev->status) {
1750 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001751 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001752 } else if (ev->link_type != ACL_LINK)
1753 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001754
1755unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001757
1758 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759}
1760
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001761static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001763 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764 int mask = hdev->link_mode;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001765 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001767 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001768 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001770 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1771 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772
Szymon Janc138d22e2011-02-17 16:44:23 +01001773 if ((mask & HCI_LM_ACCEPT) &&
Marcel Holtmannb9ee0a72013-10-17 17:24:13 -07001774 !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001776 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778
1779 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001780
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001781 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1782 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001783 memcpy(ie->data.dev_class, ev->dev_class, 3);
1784
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001785 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1786 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001788 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1789 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001790 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 hci_dev_unlock(hdev);
1792 return;
1793 }
1794 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001795
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001797
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 hci_dev_unlock(hdev);
1799
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001800 if (ev->link_type == ACL_LINK ||
1801 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001802 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001803 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001805 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001807 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1808 cp.role = 0x00; /* Become master */
1809 else
1810 cp.role = 0x01; /* Remain slave */
1811
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001812 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1813 &cp);
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001814 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001815 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001816 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001817
1818 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001819 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001820
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001821 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1822 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1823 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001824 cp.content_format = cpu_to_le16(hdev->voice_setting);
1825 cp.retrans_effort = 0xff;
1826
1827 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001828 sizeof(cp), &cp);
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001829 } else {
1830 conn->state = BT_CONNECT2;
1831 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001832 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 } else {
1834 /* Connection rejected */
1835 struct hci_cp_reject_conn_req cp;
1836
1837 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001838 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001839 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 }
1841}
1842
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001843static u8 hci_to_mgmt_reason(u8 err)
1844{
1845 switch (err) {
1846 case HCI_ERROR_CONNECTION_TIMEOUT:
1847 return MGMT_DEV_DISCONN_TIMEOUT;
1848 case HCI_ERROR_REMOTE_USER_TERM:
1849 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1850 case HCI_ERROR_REMOTE_POWER_OFF:
1851 return MGMT_DEV_DISCONN_REMOTE;
1852 case HCI_ERROR_LOCAL_HOST_TERM:
1853 return MGMT_DEV_DISCONN_LOCAL_HOST;
1854 default:
1855 return MGMT_DEV_DISCONN_UNKNOWN;
1856 }
1857}
1858
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001859static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001861 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Andre Guedesabf54a52013-11-07 17:36:09 -03001862 u8 reason = hci_to_mgmt_reason(ev->reason);
Andre Guedes9fcb18e2014-02-26 20:21:48 -03001863 struct hci_conn_params *params;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001864 struct hci_conn *conn;
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02001865 bool mgmt_connected;
Andre Guedes38462202013-11-07 17:36:10 -03001866 u8 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001868 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870 hci_dev_lock(hdev);
1871
Marcel Holtmann04837f62006-07-03 10:02:33 +02001872 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001873 if (!conn)
1874 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001875
Andre Guedesabf54a52013-11-07 17:36:09 -03001876 if (ev->status) {
1877 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1878 conn->dst_type, ev->status);
1879 goto unlock;
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001880 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001881
Andre Guedes38462202013-11-07 17:36:10 -03001882 conn->state = BT_CLOSED;
1883
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02001884 mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
1885 mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
1886 reason, mgmt_connected);
Andre Guedesabf54a52013-11-07 17:36:09 -03001887
Andre Guedes38462202013-11-07 17:36:10 -03001888 if (conn->type == ACL_LINK && conn->flush_key)
1889 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg22102462013-10-05 12:01:06 +02001890
Andre Guedes9fcb18e2014-02-26 20:21:48 -03001891 params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
1892 if (params) {
1893 switch (params->auto_connect) {
1894 case HCI_AUTO_CONN_LINK_LOSS:
1895 if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
1896 break;
1897 /* Fall through */
1898
1899 case HCI_AUTO_CONN_ALWAYS:
1900 hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type);
1901 break;
1902
1903 default:
1904 break;
1905 }
1906 }
1907
Andre Guedes38462202013-11-07 17:36:10 -03001908 type = conn->type;
Johan Hedberg22102462013-10-05 12:01:06 +02001909
Andre Guedes38462202013-11-07 17:36:10 -03001910 hci_proto_disconn_cfm(conn, ev->reason);
1911 hci_conn_del(conn);
1912
1913 /* Re-enable advertising if necessary, since it might
1914 * have been disabled by the connection. From the
1915 * HCI_LE_Set_Advertise_Enable command description in
1916 * the core specification (v4.0):
1917 * "The Controller shall continue advertising until the Host
1918 * issues an LE_Set_Advertise_Enable command with
1919 * Advertising_Enable set to 0x00 (Advertising is disabled)
1920 * or until a connection is created or until the Advertising
1921 * is timed out due to Directed Advertising."
1922 */
1923 if (type == LE_LINK)
1924 mgmt_reenable_advertising(hdev);
Johan Hedbergf7520542011-01-20 12:34:39 +02001925
1926unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927 hci_dev_unlock(hdev);
1928}
1929
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001930static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001931{
1932 struct hci_ev_auth_complete *ev = (void *) skb->data;
1933 struct hci_conn *conn;
1934
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001935 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001936
1937 hci_dev_lock(hdev);
1938
1939 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001940 if (!conn)
1941 goto unlock;
1942
1943 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001944 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001945 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001946 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001947 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001948 conn->link_mode |= HCI_LM_AUTH;
1949 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001950 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001951 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001952 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001953 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001954 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001955
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001956 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1957 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001958
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001959 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001960 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001961 struct hci_cp_set_conn_encrypt cp;
1962 cp.handle = ev->handle;
1963 cp.encrypt = 0x01;
1964 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001965 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001966 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001967 conn->state = BT_CONNECTED;
1968 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001969 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001970 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001971 } else {
1972 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001973
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001974 hci_conn_hold(conn);
1975 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001976 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001977 }
1978
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001979 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001980 if (!ev->status) {
1981 struct hci_cp_set_conn_encrypt cp;
1982 cp.handle = ev->handle;
1983 cp.encrypt = 0x01;
1984 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001985 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001986 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001987 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001988 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001989 }
1990 }
1991
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001992unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001993 hci_dev_unlock(hdev);
1994}
1995
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001996static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001997{
Johan Hedberg127178d2010-11-18 22:22:29 +02001998 struct hci_ev_remote_name *ev = (void *) skb->data;
1999 struct hci_conn *conn;
2000
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002001 BT_DBG("%s", hdev->name);
2002
2003 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02002004
2005 hci_dev_lock(hdev);
2006
2007 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002008
2009 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2010 goto check_auth;
2011
2012 if (ev->status == 0)
2013 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002014 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002015 else
2016 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2017
2018check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002019 if (!conn)
2020 goto unlock;
2021
2022 if (!hci_outgoing_auth_needed(hdev, conn))
2023 goto unlock;
2024
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002025 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002026 struct hci_cp_auth_requested cp;
2027 cp.handle = __cpu_to_le16(conn->handle);
2028 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2029 }
2030
Johan Hedberg79c6c702011-04-28 11:28:55 -07002031unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002032 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002033}
2034
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002035static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002036{
2037 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2038 struct hci_conn *conn;
2039
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002040 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002041
2042 hci_dev_lock(hdev);
2043
2044 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002045 if (!conn)
2046 goto unlock;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002047
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002048 if (!ev->status) {
2049 if (ev->encrypt) {
2050 /* Encryption implies authentication */
2051 conn->link_mode |= HCI_LM_AUTH;
2052 conn->link_mode |= HCI_LM_ENCRYPT;
2053 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002054
Marcel Holtmann914a6ff2014-02-01 11:52:02 -08002055 /* P-256 authentication key implies FIPS */
2056 if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
2057 conn->link_mode |= HCI_LM_FIPS;
2058
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002059 if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
2060 conn->type == LE_LINK)
2061 set_bit(HCI_CONN_AES_CCM, &conn->flags);
2062 } else {
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002063 conn->link_mode &= ~HCI_LM_ENCRYPT;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002064 clear_bit(HCI_CONN_AES_CCM, &conn->flags);
2065 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002066 }
2067
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002068 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2069
2070 if (ev->status && conn->state == BT_CONNECTED) {
2071 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
2072 hci_conn_drop(conn);
2073 goto unlock;
2074 }
2075
2076 if (conn->state == BT_CONFIG) {
2077 if (!ev->status)
2078 conn->state = BT_CONNECTED;
2079
2080 hci_proto_connect_cfm(conn, ev->status);
2081 hci_conn_drop(conn);
2082 } else
2083 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
2084
Gustavo Padovana7d77232012-05-13 03:20:07 -03002085unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002086 hci_dev_unlock(hdev);
2087}
2088
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002089static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2090 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002091{
2092 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2093 struct hci_conn *conn;
2094
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002095 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002096
2097 hci_dev_lock(hdev);
2098
2099 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2100 if (conn) {
2101 if (!ev->status)
2102 conn->link_mode |= HCI_LM_SECURE;
2103
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002104 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002105
2106 hci_key_change_cfm(conn, ev->status);
2107 }
2108
2109 hci_dev_unlock(hdev);
2110}
2111
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002112static void hci_remote_features_evt(struct hci_dev *hdev,
2113 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002114{
2115 struct hci_ev_remote_features *ev = (void *) skb->data;
2116 struct hci_conn *conn;
2117
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002118 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002119
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002120 hci_dev_lock(hdev);
2121
2122 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002123 if (!conn)
2124 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002125
Johan Hedbergccd556f2010-11-10 17:11:51 +02002126 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002127 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002128
2129 if (conn->state != BT_CONFIG)
2130 goto unlock;
2131
2132 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2133 struct hci_cp_read_remote_ext_features cp;
2134 cp.handle = ev->handle;
2135 cp.page = 0x01;
2136 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002137 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002138 goto unlock;
2139 }
2140
Johan Hedberg671267b2012-05-12 16:11:50 -03002141 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002142 struct hci_cp_remote_name_req cp;
2143 memset(&cp, 0, sizeof(cp));
2144 bacpy(&cp.bdaddr, &conn->dst);
2145 cp.pscan_rep_mode = 0x02;
2146 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002147 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2148 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002149 conn->dst_type, 0, NULL, 0,
2150 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002151
Johan Hedberg127178d2010-11-18 22:22:29 +02002152 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002153 conn->state = BT_CONNECTED;
2154 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002155 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002156 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002157
Johan Hedbergccd556f2010-11-10 17:11:51 +02002158unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002159 hci_dev_unlock(hdev);
2160}
2161
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002162static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002163{
2164 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002165 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002166 __u16 opcode;
2167
2168 skb_pull(skb, sizeof(*ev));
2169
2170 opcode = __le16_to_cpu(ev->opcode);
2171
2172 switch (opcode) {
2173 case HCI_OP_INQUIRY_CANCEL:
2174 hci_cc_inquiry_cancel(hdev, skb);
2175 break;
2176
Andre Guedes4d934832012-03-21 00:03:35 -03002177 case HCI_OP_PERIODIC_INQ:
2178 hci_cc_periodic_inq(hdev, skb);
2179 break;
2180
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002181 case HCI_OP_EXIT_PERIODIC_INQ:
2182 hci_cc_exit_periodic_inq(hdev, skb);
2183 break;
2184
2185 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2186 hci_cc_remote_name_req_cancel(hdev, skb);
2187 break;
2188
2189 case HCI_OP_ROLE_DISCOVERY:
2190 hci_cc_role_discovery(hdev, skb);
2191 break;
2192
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002193 case HCI_OP_READ_LINK_POLICY:
2194 hci_cc_read_link_policy(hdev, skb);
2195 break;
2196
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002197 case HCI_OP_WRITE_LINK_POLICY:
2198 hci_cc_write_link_policy(hdev, skb);
2199 break;
2200
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002201 case HCI_OP_READ_DEF_LINK_POLICY:
2202 hci_cc_read_def_link_policy(hdev, skb);
2203 break;
2204
2205 case HCI_OP_WRITE_DEF_LINK_POLICY:
2206 hci_cc_write_def_link_policy(hdev, skb);
2207 break;
2208
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002209 case HCI_OP_RESET:
2210 hci_cc_reset(hdev, skb);
2211 break;
2212
2213 case HCI_OP_WRITE_LOCAL_NAME:
2214 hci_cc_write_local_name(hdev, skb);
2215 break;
2216
2217 case HCI_OP_READ_LOCAL_NAME:
2218 hci_cc_read_local_name(hdev, skb);
2219 break;
2220
2221 case HCI_OP_WRITE_AUTH_ENABLE:
2222 hci_cc_write_auth_enable(hdev, skb);
2223 break;
2224
2225 case HCI_OP_WRITE_ENCRYPT_MODE:
2226 hci_cc_write_encrypt_mode(hdev, skb);
2227 break;
2228
2229 case HCI_OP_WRITE_SCAN_ENABLE:
2230 hci_cc_write_scan_enable(hdev, skb);
2231 break;
2232
2233 case HCI_OP_READ_CLASS_OF_DEV:
2234 hci_cc_read_class_of_dev(hdev, skb);
2235 break;
2236
2237 case HCI_OP_WRITE_CLASS_OF_DEV:
2238 hci_cc_write_class_of_dev(hdev, skb);
2239 break;
2240
2241 case HCI_OP_READ_VOICE_SETTING:
2242 hci_cc_read_voice_setting(hdev, skb);
2243 break;
2244
2245 case HCI_OP_WRITE_VOICE_SETTING:
2246 hci_cc_write_voice_setting(hdev, skb);
2247 break;
2248
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002249 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2250 hci_cc_read_num_supported_iac(hdev, skb);
2251 break;
2252
Marcel Holtmann333140b2008-07-14 20:13:48 +02002253 case HCI_OP_WRITE_SSP_MODE:
2254 hci_cc_write_ssp_mode(hdev, skb);
2255 break;
2256
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08002257 case HCI_OP_WRITE_SC_SUPPORT:
2258 hci_cc_write_sc_support(hdev, skb);
2259 break;
2260
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002261 case HCI_OP_READ_LOCAL_VERSION:
2262 hci_cc_read_local_version(hdev, skb);
2263 break;
2264
2265 case HCI_OP_READ_LOCAL_COMMANDS:
2266 hci_cc_read_local_commands(hdev, skb);
2267 break;
2268
2269 case HCI_OP_READ_LOCAL_FEATURES:
2270 hci_cc_read_local_features(hdev, skb);
2271 break;
2272
Andre Guedes971e3a42011-06-30 19:20:52 -03002273 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2274 hci_cc_read_local_ext_features(hdev, skb);
2275 break;
2276
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002277 case HCI_OP_READ_BUFFER_SIZE:
2278 hci_cc_read_buffer_size(hdev, skb);
2279 break;
2280
2281 case HCI_OP_READ_BD_ADDR:
2282 hci_cc_read_bd_addr(hdev, skb);
2283 break;
2284
Johan Hedbergf332ec62013-03-15 17:07:11 -05002285 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2286 hci_cc_read_page_scan_activity(hdev, skb);
2287 break;
2288
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002289 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2290 hci_cc_write_page_scan_activity(hdev, skb);
2291 break;
2292
Johan Hedbergf332ec62013-03-15 17:07:11 -05002293 case HCI_OP_READ_PAGE_SCAN_TYPE:
2294 hci_cc_read_page_scan_type(hdev, skb);
2295 break;
2296
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002297 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2298 hci_cc_write_page_scan_type(hdev, skb);
2299 break;
2300
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002301 case HCI_OP_READ_DATA_BLOCK_SIZE:
2302 hci_cc_read_data_block_size(hdev, skb);
2303 break;
2304
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002305 case HCI_OP_READ_FLOW_CONTROL_MODE:
2306 hci_cc_read_flow_control_mode(hdev, skb);
2307 break;
2308
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002309 case HCI_OP_READ_LOCAL_AMP_INFO:
2310 hci_cc_read_local_amp_info(hdev, skb);
2311 break;
2312
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002313 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2314 hci_cc_read_local_amp_assoc(hdev, skb);
2315 break;
2316
Johan Hedbergd5859e22011-01-25 01:19:58 +02002317 case HCI_OP_READ_INQ_RSP_TX_POWER:
2318 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2319 break;
2320
Johan Hedberg980e1a52011-01-22 06:10:07 +02002321 case HCI_OP_PIN_CODE_REPLY:
2322 hci_cc_pin_code_reply(hdev, skb);
2323 break;
2324
2325 case HCI_OP_PIN_CODE_NEG_REPLY:
2326 hci_cc_pin_code_neg_reply(hdev, skb);
2327 break;
2328
Szymon Jancc35938b2011-03-22 13:12:21 +01002329 case HCI_OP_READ_LOCAL_OOB_DATA:
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08002330 hci_cc_read_local_oob_data(hdev, skb);
2331 break;
2332
2333 case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
2334 hci_cc_read_local_oob_ext_data(hdev, skb);
Szymon Jancc35938b2011-03-22 13:12:21 +01002335 break;
2336
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002337 case HCI_OP_LE_READ_BUFFER_SIZE:
2338 hci_cc_le_read_buffer_size(hdev, skb);
2339 break;
2340
Johan Hedberg60e77322013-01-22 14:01:59 +02002341 case HCI_OP_LE_READ_LOCAL_FEATURES:
2342 hci_cc_le_read_local_features(hdev, skb);
2343 break;
2344
Johan Hedberg8fa19092012-10-19 20:57:49 +03002345 case HCI_OP_LE_READ_ADV_TX_POWER:
2346 hci_cc_le_read_adv_tx_power(hdev, skb);
2347 break;
2348
Johan Hedberga5c29682011-02-19 12:05:57 -03002349 case HCI_OP_USER_CONFIRM_REPLY:
2350 hci_cc_user_confirm_reply(hdev, skb);
2351 break;
2352
2353 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2354 hci_cc_user_confirm_neg_reply(hdev, skb);
2355 break;
2356
Brian Gix1143d452011-11-23 08:28:34 -08002357 case HCI_OP_USER_PASSKEY_REPLY:
2358 hci_cc_user_passkey_reply(hdev, skb);
2359 break;
2360
2361 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2362 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002363 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002364
Marcel Holtmann7a4cd512014-02-19 19:52:13 -08002365 case HCI_OP_LE_SET_RANDOM_ADDR:
2366 hci_cc_le_set_random_addr(hdev, skb);
2367 break;
2368
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002369 case HCI_OP_LE_SET_ADV_ENABLE:
2370 hci_cc_le_set_adv_enable(hdev, skb);
2371 break;
2372
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002373 case HCI_OP_LE_SET_SCAN_ENABLE:
2374 hci_cc_le_set_scan_enable(hdev, skb);
2375 break;
2376
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002377 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2378 hci_cc_le_read_white_list_size(hdev, skb);
2379 break;
2380
Johan Hedberg9b008c02013-01-22 14:02:01 +02002381 case HCI_OP_LE_READ_SUPPORTED_STATES:
2382 hci_cc_le_read_supported_states(hdev, skb);
2383 break;
2384
Andre Guedesf9b49302011-06-30 19:20:53 -03002385 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2386 hci_cc_write_le_host_supported(hdev, skb);
2387 break;
2388
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02002389 case HCI_OP_LE_SET_ADV_PARAM:
2390 hci_cc_set_adv_param(hdev, skb);
2391 break;
2392
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002393 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2394 hci_cc_write_remote_amp_assoc(hdev, skb);
2395 break;
2396
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002397 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002398 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002399 break;
2400 }
2401
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002402 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002403 del_timer(&hdev->cmd_timer);
2404
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002405 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002406
Szymon Jancdbccd792012-12-11 08:51:19 +01002407 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002408 atomic_set(&hdev->cmd_cnt, 1);
2409 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002410 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002411 }
2412}
2413
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002414static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002415{
2416 struct hci_ev_cmd_status *ev = (void *) skb->data;
2417 __u16 opcode;
2418
2419 skb_pull(skb, sizeof(*ev));
2420
2421 opcode = __le16_to_cpu(ev->opcode);
2422
2423 switch (opcode) {
2424 case HCI_OP_INQUIRY:
2425 hci_cs_inquiry(hdev, ev->status);
2426 break;
2427
2428 case HCI_OP_CREATE_CONN:
2429 hci_cs_create_conn(hdev, ev->status);
2430 break;
2431
2432 case HCI_OP_ADD_SCO:
2433 hci_cs_add_sco(hdev, ev->status);
2434 break;
2435
Marcel Holtmannf8558552008-07-14 20:13:49 +02002436 case HCI_OP_AUTH_REQUESTED:
2437 hci_cs_auth_requested(hdev, ev->status);
2438 break;
2439
2440 case HCI_OP_SET_CONN_ENCRYPT:
2441 hci_cs_set_conn_encrypt(hdev, ev->status);
2442 break;
2443
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002444 case HCI_OP_REMOTE_NAME_REQ:
2445 hci_cs_remote_name_req(hdev, ev->status);
2446 break;
2447
Marcel Holtmann769be972008-07-14 20:13:49 +02002448 case HCI_OP_READ_REMOTE_FEATURES:
2449 hci_cs_read_remote_features(hdev, ev->status);
2450 break;
2451
2452 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2453 hci_cs_read_remote_ext_features(hdev, ev->status);
2454 break;
2455
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002456 case HCI_OP_SETUP_SYNC_CONN:
2457 hci_cs_setup_sync_conn(hdev, ev->status);
2458 break;
2459
2460 case HCI_OP_SNIFF_MODE:
2461 hci_cs_sniff_mode(hdev, ev->status);
2462 break;
2463
2464 case HCI_OP_EXIT_SNIFF_MODE:
2465 hci_cs_exit_sniff_mode(hdev, ev->status);
2466 break;
2467
Johan Hedberg8962ee72011-01-20 12:40:27 +02002468 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002469 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002470 break;
2471
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002472 case HCI_OP_CREATE_PHY_LINK:
2473 hci_cs_create_phylink(hdev, ev->status);
2474 break;
2475
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002476 case HCI_OP_ACCEPT_PHY_LINK:
2477 hci_cs_accept_phylink(hdev, ev->status);
2478 break;
2479
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002480 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002481 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002482 break;
2483 }
2484
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002485 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002486 del_timer(&hdev->cmd_timer);
2487
Johan Hedberg02350a72013-04-03 21:50:29 +03002488 if (ev->status ||
2489 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2490 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002491
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002492 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002493 atomic_set(&hdev->cmd_cnt, 1);
2494 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002495 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002496 }
2497}
2498
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002499static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002500{
2501 struct hci_ev_role_change *ev = (void *) skb->data;
2502 struct hci_conn *conn;
2503
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002504 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002505
2506 hci_dev_lock(hdev);
2507
2508 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2509 if (conn) {
2510 if (!ev->status) {
2511 if (ev->role)
2512 conn->link_mode &= ~HCI_LM_MASTER;
2513 else
2514 conn->link_mode |= HCI_LM_MASTER;
2515 }
2516
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002517 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002518
2519 hci_role_switch_cfm(conn, ev->status, ev->role);
2520 }
2521
2522 hci_dev_unlock(hdev);
2523}
2524
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002525static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002527 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002528 int i;
2529
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002530 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2531 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2532 return;
2533 }
2534
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002535 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002536 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002537 BT_DBG("%s bad parameters", hdev->name);
2538 return;
2539 }
2540
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002541 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2542
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002543 for (i = 0; i < ev->num_hndl; i++) {
2544 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002545 struct hci_conn *conn;
2546 __u16 handle, count;
2547
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002548 handle = __le16_to_cpu(info->handle);
2549 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002550
2551 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002552 if (!conn)
2553 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002554
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002555 conn->sent -= count;
2556
2557 switch (conn->type) {
2558 case ACL_LINK:
2559 hdev->acl_cnt += count;
2560 if (hdev->acl_cnt > hdev->acl_pkts)
2561 hdev->acl_cnt = hdev->acl_pkts;
2562 break;
2563
2564 case LE_LINK:
2565 if (hdev->le_pkts) {
2566 hdev->le_cnt += count;
2567 if (hdev->le_cnt > hdev->le_pkts)
2568 hdev->le_cnt = hdev->le_pkts;
2569 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002570 hdev->acl_cnt += count;
2571 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002572 hdev->acl_cnt = hdev->acl_pkts;
2573 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002574 break;
2575
2576 case SCO_LINK:
2577 hdev->sco_cnt += count;
2578 if (hdev->sco_cnt > hdev->sco_pkts)
2579 hdev->sco_cnt = hdev->sco_pkts;
2580 break;
2581
2582 default:
2583 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2584 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002585 }
2586 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002587
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002588 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002589}
2590
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002591static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2592 __u16 handle)
2593{
2594 struct hci_chan *chan;
2595
2596 switch (hdev->dev_type) {
2597 case HCI_BREDR:
2598 return hci_conn_hash_lookup_handle(hdev, handle);
2599 case HCI_AMP:
2600 chan = hci_chan_lookup_handle(hdev, handle);
2601 if (chan)
2602 return chan->conn;
2603 break;
2604 default:
2605 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2606 break;
2607 }
2608
2609 return NULL;
2610}
2611
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002612static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002613{
2614 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2615 int i;
2616
2617 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2618 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2619 return;
2620 }
2621
2622 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002623 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002624 BT_DBG("%s bad parameters", hdev->name);
2625 return;
2626 }
2627
2628 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002629 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002630
2631 for (i = 0; i < ev->num_hndl; i++) {
2632 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002633 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002634 __u16 handle, block_count;
2635
2636 handle = __le16_to_cpu(info->handle);
2637 block_count = __le16_to_cpu(info->blocks);
2638
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002639 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002640 if (!conn)
2641 continue;
2642
2643 conn->sent -= block_count;
2644
2645 switch (conn->type) {
2646 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002647 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002648 hdev->block_cnt += block_count;
2649 if (hdev->block_cnt > hdev->num_blocks)
2650 hdev->block_cnt = hdev->num_blocks;
2651 break;
2652
2653 default:
2654 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2655 break;
2656 }
2657 }
2658
2659 queue_work(hdev->workqueue, &hdev->tx_work);
2660}
2661
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002662static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002664 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002665 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002667 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002668
2669 hci_dev_lock(hdev);
2670
Marcel Holtmann04837f62006-07-03 10:02:33 +02002671 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2672 if (conn) {
2673 conn->mode = ev->mode;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002674
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002675 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2676 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002677 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002678 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002679 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002680 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002681 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002682
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002683 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002684 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002685 }
2686
2687 hci_dev_unlock(hdev);
2688}
2689
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002690static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002691{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002692 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2693 struct hci_conn *conn;
2694
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002695 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002696
2697 hci_dev_lock(hdev);
2698
2699 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002700 if (!conn)
2701 goto unlock;
2702
2703 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002704 hci_conn_hold(conn);
2705 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002706 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002707 }
2708
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002709 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002710 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002711 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002712 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002713 u8 secure;
2714
2715 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2716 secure = 1;
2717 else
2718 secure = 0;
2719
Johan Hedberg744cf192011-11-08 20:40:14 +02002720 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002721 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002722
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002723unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002724 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725}
2726
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002727static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002729 struct hci_ev_link_key_req *ev = (void *) skb->data;
2730 struct hci_cp_link_key_reply cp;
2731 struct hci_conn *conn;
2732 struct link_key *key;
2733
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002734 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002735
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002736 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002737 return;
2738
2739 hci_dev_lock(hdev);
2740
2741 key = hci_find_link_key(hdev, &ev->bdaddr);
2742 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002743 BT_DBG("%s link key not found for %pMR", hdev->name,
2744 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002745 goto not_found;
2746 }
2747
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002748 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2749 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002750
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002751 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002752 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002753 BT_DBG("%s ignoring debug key", hdev->name);
2754 goto not_found;
2755 }
2756
2757 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002758 if (conn) {
Marcel Holtmann66138ce2014-01-10 02:07:20 -08002759 if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
2760 key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002761 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002762 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2763 goto not_found;
2764 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002765
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002766 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002767 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002768 BT_DBG("%s ignoring key unauthenticated for high security",
2769 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002770 goto not_found;
2771 }
2772
2773 conn->key_type = key->type;
2774 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002775 }
2776
2777 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002778 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002779
2780 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2781
2782 hci_dev_unlock(hdev);
2783
2784 return;
2785
2786not_found:
2787 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2788 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002789}
2790
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002791static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002792{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002793 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2794 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002795 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002796
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002797 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002798
2799 hci_dev_lock(hdev);
2800
2801 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2802 if (conn) {
2803 hci_conn_hold(conn);
2804 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002805 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002806
2807 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2808 conn->key_type = ev->key_type;
2809
David Herrmann76a68ba2013-04-06 20:28:37 +02002810 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002811 }
2812
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002813 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002814 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002815 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002816
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002817 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818}
2819
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002820static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002821{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002822 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002823 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 Holtmann04837f62006-07-03 10:02:33 +02002826
2827 hci_dev_lock(hdev);
2828
2829 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830 if (conn && !ev->status) {
2831 struct inquiry_entry *ie;
2832
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002833 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2834 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002835 ie->data.clock_offset = ev->clock_offset;
2836 ie->timestamp = jiffies;
2837 }
2838 }
2839
2840 hci_dev_unlock(hdev);
2841}
2842
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002843static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002844{
2845 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2846 struct hci_conn *conn;
2847
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002848 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002849
2850 hci_dev_lock(hdev);
2851
2852 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2853 if (conn && !ev->status)
2854 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2855
2856 hci_dev_unlock(hdev);
2857}
2858
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002859static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002860{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002861 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002862 struct inquiry_entry *ie;
2863
2864 BT_DBG("%s", hdev->name);
2865
2866 hci_dev_lock(hdev);
2867
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002868 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2869 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002870 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2871 ie->timestamp = jiffies;
2872 }
2873
2874 hci_dev_unlock(hdev);
2875}
2876
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002877static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2878 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002879{
2880 struct inquiry_data data;
2881 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002882 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002883
2884 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2885
2886 if (!num_rsp)
2887 return;
2888
Andre Guedes1519cc12012-03-21 00:03:38 -03002889 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2890 return;
2891
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002892 hci_dev_lock(hdev);
2893
2894 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002895 struct inquiry_info_with_rssi_and_pscan_mode *info;
2896 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002897
Johan Hedberge17acd42011-03-30 23:57:16 +03002898 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002899 bacpy(&data.bdaddr, &info->bdaddr);
2900 data.pscan_rep_mode = info->pscan_rep_mode;
2901 data.pscan_period_mode = info->pscan_period_mode;
2902 data.pscan_mode = info->pscan_mode;
2903 memcpy(data.dev_class, info->dev_class, 3);
2904 data.clock_offset = info->clock_offset;
2905 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002906 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002907
2908 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002909 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002910 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002911 info->dev_class, info->rssi,
2912 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002913 }
2914 } else {
2915 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2916
Johan Hedberge17acd42011-03-30 23:57:16 +03002917 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002918 bacpy(&data.bdaddr, &info->bdaddr);
2919 data.pscan_rep_mode = info->pscan_rep_mode;
2920 data.pscan_period_mode = info->pscan_period_mode;
2921 data.pscan_mode = 0x00;
2922 memcpy(data.dev_class, info->dev_class, 3);
2923 data.clock_offset = info->clock_offset;
2924 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002925 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002926 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002927 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002928 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002929 info->dev_class, info->rssi,
2930 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002931 }
2932 }
2933
2934 hci_dev_unlock(hdev);
2935}
2936
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002937static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2938 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002939{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002940 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2941 struct hci_conn *conn;
2942
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002943 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002944
Marcel Holtmann41a96212008-07-14 20:13:48 +02002945 hci_dev_lock(hdev);
2946
2947 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002948 if (!conn)
2949 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002950
Johan Hedbergcad718e2013-04-17 15:00:51 +03002951 if (ev->page < HCI_MAX_PAGES)
2952 memcpy(conn->features[ev->page], ev->features, 8);
2953
Johan Hedbergccd556f2010-11-10 17:11:51 +02002954 if (!ev->status && ev->page == 0x01) {
2955 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002956
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002957 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2958 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002959 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002960
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302961 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002962 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302963 } else {
2964 /* It is mandatory by the Bluetooth specification that
2965 * Extended Inquiry Results are only used when Secure
2966 * Simple Pairing is enabled, but some devices violate
2967 * this.
2968 *
2969 * To make these devices work, the internal SSP
2970 * enabled flag needs to be cleared if the remote host
2971 * features do not indicate SSP support */
2972 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2973 }
Marcel Holtmanneb9a8f32014-01-15 22:37:38 -08002974
2975 if (ev->features[0] & LMP_HOST_SC)
2976 set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002977 }
2978
Johan Hedbergccd556f2010-11-10 17:11:51 +02002979 if (conn->state != BT_CONFIG)
2980 goto unlock;
2981
Johan Hedberg671267b2012-05-12 16:11:50 -03002982 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002983 struct hci_cp_remote_name_req cp;
2984 memset(&cp, 0, sizeof(cp));
2985 bacpy(&cp.bdaddr, &conn->dst);
2986 cp.pscan_rep_mode = 0x02;
2987 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002988 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2989 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002990 conn->dst_type, 0, NULL, 0,
2991 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002992
Johan Hedberg127178d2010-11-18 22:22:29 +02002993 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002994 conn->state = BT_CONNECTED;
2995 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002996 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002997 }
2998
2999unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02003000 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003001}
3002
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003003static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
3004 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003005{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003006 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
3007 struct hci_conn *conn;
3008
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003009 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003010
3011 hci_dev_lock(hdev);
3012
3013 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02003014 if (!conn) {
3015 if (ev->link_type == ESCO_LINK)
3016 goto unlock;
3017
3018 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
3019 if (!conn)
3020 goto unlock;
3021
3022 conn->type = SCO_LINK;
3023 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003024
Marcel Holtmann732547f2009-04-19 19:14:14 +02003025 switch (ev->status) {
3026 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003027 conn->handle = __le16_to_cpu(ev->handle);
3028 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02003029
3030 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02003031 break;
3032
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02003033 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05003034 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003035 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08003036 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003037 case 0x1f: /* Unspecified error */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003038 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02003039 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
3040 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003041 if (hci_setup_sync(conn, conn->link->handle))
3042 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003043 }
3044 /* fall through */
3045
3046 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003047 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003048 break;
3049 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003050
3051 hci_proto_connect_cfm(conn, ev->status);
3052 if (ev->status)
3053 hci_conn_del(conn);
3054
3055unlock:
3056 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003057}
3058
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07003059static inline size_t eir_get_length(u8 *eir, size_t eir_len)
3060{
3061 size_t parsed = 0;
3062
3063 while (parsed < eir_len) {
3064 u8 field_len = eir[0];
3065
3066 if (field_len == 0)
3067 return parsed;
3068
3069 parsed += field_len + 1;
3070 eir += field_len + 1;
3071 }
3072
3073 return eir_len;
3074}
3075
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003076static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3077 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003078{
3079 struct inquiry_data data;
3080 struct extended_inquiry_info *info = (void *) (skb->data + 1);
3081 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303082 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003083
3084 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3085
3086 if (!num_rsp)
3087 return;
3088
Andre Guedes1519cc12012-03-21 00:03:38 -03003089 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3090 return;
3091
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003092 hci_dev_lock(hdev);
3093
Johan Hedberge17acd42011-03-30 23:57:16 +03003094 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003095 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003096
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003097 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003098 data.pscan_rep_mode = info->pscan_rep_mode;
3099 data.pscan_period_mode = info->pscan_period_mode;
3100 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003101 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003102 data.clock_offset = info->clock_offset;
3103 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003104 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003105
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003106 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003107 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003108 sizeof(info->data),
3109 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003110 else
3111 name_known = true;
3112
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003113 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003114 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303115 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003116 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003117 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303118 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003119 }
3120
3121 hci_dev_unlock(hdev);
3122}
3123
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003124static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3125 struct sk_buff *skb)
3126{
3127 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3128 struct hci_conn *conn;
3129
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003130 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003131 __le16_to_cpu(ev->handle));
3132
3133 hci_dev_lock(hdev);
3134
3135 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3136 if (!conn)
3137 goto unlock;
3138
3139 if (!ev->status)
3140 conn->sec_level = conn->pending_sec_level;
3141
3142 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3143
3144 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003145 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003146 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003147 goto unlock;
3148 }
3149
3150 if (conn->state == BT_CONFIG) {
3151 if (!ev->status)
3152 conn->state = BT_CONNECTED;
3153
3154 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003155 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003156 } else {
3157 hci_auth_cfm(conn, ev->status);
3158
3159 hci_conn_hold(conn);
3160 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003161 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003162 }
3163
3164unlock:
3165 hci_dev_unlock(hdev);
3166}
3167
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003168static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003169{
3170 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003171 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3172 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003173 /* If both remote and local IO capabilities allow MITM
3174 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003175 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3176 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3177 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003178 else
Mikel Astizacabae92013-06-28 10:56:28 +02003179 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003180 }
3181
3182 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003183 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3184 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003185 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003186
3187 return conn->auth_type;
3188}
3189
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003190static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003191{
3192 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3193 struct hci_conn *conn;
3194
3195 BT_DBG("%s", hdev->name);
3196
3197 hci_dev_lock(hdev);
3198
3199 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003200 if (!conn)
3201 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003202
Johan Hedberg03b555e2011-01-04 15:40:05 +02003203 hci_conn_hold(conn);
3204
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003205 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003206 goto unlock;
3207
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003208 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003209 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003210 struct hci_cp_io_capability_reply cp;
3211
3212 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303213 /* Change the IO capability from KeyboardDisplay
3214 * to DisplayYesNo as it is not supported by BT spec. */
3215 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003216 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003217 conn->auth_type = hci_get_auth_req(conn);
3218 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003219
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003220 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3221 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003222 cp.oob_data = 0x01;
3223 else
3224 cp.oob_data = 0x00;
3225
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003226 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003227 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003228 } else {
3229 struct hci_cp_io_capability_neg_reply cp;
3230
3231 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003232 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003233
3234 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003235 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003236 }
3237
3238unlock:
3239 hci_dev_unlock(hdev);
3240}
3241
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003242static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003243{
3244 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3245 struct hci_conn *conn;
3246
3247 BT_DBG("%s", hdev->name);
3248
3249 hci_dev_lock(hdev);
3250
3251 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3252 if (!conn)
3253 goto unlock;
3254
Johan Hedberg03b555e2011-01-04 15:40:05 +02003255 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003256 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003257 if (ev->oob_data)
3258 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003259
3260unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003261 hci_dev_unlock(hdev);
3262}
3263
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003264static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3265 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003266{
3267 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003268 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003269 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003270
3271 BT_DBG("%s", hdev->name);
3272
3273 hci_dev_lock(hdev);
3274
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003275 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003276 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003277
Johan Hedberg7a828902011-04-28 11:28:53 -07003278 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3279 if (!conn)
3280 goto unlock;
3281
3282 loc_mitm = (conn->auth_type & 0x01);
3283 rem_mitm = (conn->remote_auth & 0x01);
3284
3285 /* If we require MITM but the remote device can't provide that
3286 * (it has NoInputNoOutput) then reject the confirmation
3287 * request. The only exception is when we're dedicated bonding
3288 * initiators (connect_cfm_cb set) since then we always have the MITM
3289 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003290 if (!conn->connect_cfm_cb && loc_mitm &&
3291 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003292 BT_DBG("Rejecting request: remote device can't provide MITM");
3293 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003294 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003295 goto unlock;
3296 }
3297
3298 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003299 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3300 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003301
3302 /* If we're not the initiators request authorization to
3303 * proceed from user space (mgmt_user_confirm with
3304 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003305 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003306 BT_DBG("Confirming auto-accept as acceptor");
3307 confirm_hint = 1;
3308 goto confirm;
3309 }
3310
Johan Hedberg9f616562011-04-28 11:28:54 -07003311 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003312 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003313
3314 if (hdev->auto_accept_delay > 0) {
3315 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
Johan Hedberg7bc18d92013-10-16 18:11:39 +03003316 queue_delayed_work(conn->hdev->workqueue,
3317 &conn->auto_accept_work, delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003318 goto unlock;
3319 }
3320
Johan Hedberg7a828902011-04-28 11:28:53 -07003321 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003322 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003323 goto unlock;
3324 }
3325
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003326confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003327 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003328 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003329
3330unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003331 hci_dev_unlock(hdev);
3332}
3333
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003334static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3335 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003336{
3337 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3338
3339 BT_DBG("%s", hdev->name);
3340
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003341 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003342 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003343}
3344
Johan Hedberg92a25252012-09-06 18:39:26 +03003345static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3346 struct sk_buff *skb)
3347{
3348 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3349 struct hci_conn *conn;
3350
3351 BT_DBG("%s", hdev->name);
3352
3353 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3354 if (!conn)
3355 return;
3356
3357 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3358 conn->passkey_entered = 0;
3359
3360 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3361 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3362 conn->dst_type, conn->passkey_notify,
3363 conn->passkey_entered);
3364}
3365
3366static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3367{
3368 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3369 struct hci_conn *conn;
3370
3371 BT_DBG("%s", hdev->name);
3372
3373 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3374 if (!conn)
3375 return;
3376
3377 switch (ev->type) {
3378 case HCI_KEYPRESS_STARTED:
3379 conn->passkey_entered = 0;
3380 return;
3381
3382 case HCI_KEYPRESS_ENTERED:
3383 conn->passkey_entered++;
3384 break;
3385
3386 case HCI_KEYPRESS_ERASED:
3387 conn->passkey_entered--;
3388 break;
3389
3390 case HCI_KEYPRESS_CLEARED:
3391 conn->passkey_entered = 0;
3392 break;
3393
3394 case HCI_KEYPRESS_COMPLETED:
3395 return;
3396 }
3397
3398 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3399 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3400 conn->dst_type, conn->passkey_notify,
3401 conn->passkey_entered);
3402}
3403
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003404static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3405 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003406{
3407 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3408 struct hci_conn *conn;
3409
3410 BT_DBG("%s", hdev->name);
3411
3412 hci_dev_lock(hdev);
3413
3414 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003415 if (!conn)
3416 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003417
Johan Hedberg2a611692011-02-19 12:06:00 -03003418 /* To avoid duplicate auth_failed events to user space we check
3419 * the HCI_CONN_AUTH_PEND flag which will be set if we
3420 * initiated the authentication. A traditional auth_complete
3421 * event gets always produced as initiator and is also mapped to
3422 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003423 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003424 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003425 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003426
David Herrmann76a68ba2013-04-06 20:28:37 +02003427 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003428
3429unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003430 hci_dev_unlock(hdev);
3431}
3432
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003433static void hci_remote_host_features_evt(struct hci_dev *hdev,
3434 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003435{
3436 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3437 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003438 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003439
3440 BT_DBG("%s", hdev->name);
3441
3442 hci_dev_lock(hdev);
3443
Johan Hedbergcad718e2013-04-17 15:00:51 +03003444 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3445 if (conn)
3446 memcpy(conn->features[1], ev->features, 8);
3447
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003448 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3449 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003450 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003451
3452 hci_dev_unlock(hdev);
3453}
3454
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003455static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3456 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003457{
3458 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3459 struct oob_data *data;
3460
3461 BT_DBG("%s", hdev->name);
3462
3463 hci_dev_lock(hdev);
3464
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003465 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003466 goto unlock;
3467
Szymon Janc2763eda2011-03-22 13:12:22 +01003468 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3469 if (data) {
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003470 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
3471 struct hci_cp_remote_oob_ext_data_reply cp;
Szymon Janc2763eda2011-03-22 13:12:22 +01003472
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003473 bacpy(&cp.bdaddr, &ev->bdaddr);
3474 memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
3475 memcpy(cp.randomizer192, data->randomizer192,
3476 sizeof(cp.randomizer192));
3477 memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
3478 memcpy(cp.randomizer256, data->randomizer256,
3479 sizeof(cp.randomizer256));
Szymon Janc2763eda2011-03-22 13:12:22 +01003480
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003481 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
3482 sizeof(cp), &cp);
3483 } else {
3484 struct hci_cp_remote_oob_data_reply cp;
3485
3486 bacpy(&cp.bdaddr, &ev->bdaddr);
3487 memcpy(cp.hash, data->hash192, sizeof(cp.hash));
3488 memcpy(cp.randomizer, data->randomizer192,
3489 sizeof(cp.randomizer));
3490
3491 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
3492 sizeof(cp), &cp);
3493 }
Szymon Janc2763eda2011-03-22 13:12:22 +01003494 } else {
3495 struct hci_cp_remote_oob_data_neg_reply cp;
3496
3497 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003498 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
3499 sizeof(cp), &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003500 }
3501
Szymon Jance1ba1f12011-04-06 13:01:59 +02003502unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003503 hci_dev_unlock(hdev);
3504}
3505
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003506static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3507 struct sk_buff *skb)
3508{
3509 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3510 struct hci_conn *hcon, *bredr_hcon;
3511
3512 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3513 ev->status);
3514
3515 hci_dev_lock(hdev);
3516
3517 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3518 if (!hcon) {
3519 hci_dev_unlock(hdev);
3520 return;
3521 }
3522
3523 if (ev->status) {
3524 hci_conn_del(hcon);
3525 hci_dev_unlock(hdev);
3526 return;
3527 }
3528
3529 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3530
3531 hcon->state = BT_CONNECTED;
3532 bacpy(&hcon->dst, &bredr_hcon->dst);
3533
3534 hci_conn_hold(hcon);
3535 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003536 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003537
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003538 hci_conn_add_sysfs(hcon);
3539
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003540 amp_physical_cfm(bredr_hcon, hcon);
3541
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003542 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003543}
3544
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003545static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3546{
3547 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3548 struct hci_conn *hcon;
3549 struct hci_chan *hchan;
3550 struct amp_mgr *mgr;
3551
3552 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3553 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3554 ev->status);
3555
3556 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3557 if (!hcon)
3558 return;
3559
3560 /* Create AMP hchan */
3561 hchan = hci_chan_create(hcon);
3562 if (!hchan)
3563 return;
3564
3565 hchan->handle = le16_to_cpu(ev->handle);
3566
3567 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3568
3569 mgr = hcon->amp_mgr;
3570 if (mgr && mgr->bredr_chan) {
3571 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3572
3573 l2cap_chan_lock(bredr_chan);
3574
3575 bredr_chan->conn->mtu = hdev->block_mtu;
3576 l2cap_logical_cfm(bredr_chan, hchan, 0);
3577 hci_conn_hold(hcon);
3578
3579 l2cap_chan_unlock(bredr_chan);
3580 }
3581}
3582
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003583static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3584 struct sk_buff *skb)
3585{
3586 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3587 struct hci_chan *hchan;
3588
3589 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3590 le16_to_cpu(ev->handle), ev->status);
3591
3592 if (ev->status)
3593 return;
3594
3595 hci_dev_lock(hdev);
3596
3597 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3598 if (!hchan)
3599 goto unlock;
3600
3601 amp_destroy_logical_link(hchan, ev->reason);
3602
3603unlock:
3604 hci_dev_unlock(hdev);
3605}
3606
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003607static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3608 struct sk_buff *skb)
3609{
3610 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3611 struct hci_conn *hcon;
3612
3613 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3614
3615 if (ev->status)
3616 return;
3617
3618 hci_dev_lock(hdev);
3619
3620 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3621 if (hcon) {
3622 hcon->state = BT_CLOSED;
3623 hci_conn_del(hcon);
3624 }
3625
3626 hci_dev_unlock(hdev);
3627}
3628
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003629static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003630{
3631 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3632 struct hci_conn *conn;
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003633 struct smp_irk *irk;
Ville Tervofcd89c02011-02-10 22:38:47 -03003634
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003635 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003636
3637 hci_dev_lock(hdev);
3638
Andre Guedesb47a09b2012-07-27 15:10:15 -03003639 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003640 if (!conn) {
3641 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3642 if (!conn) {
3643 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003644 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003645 }
Andre Guedes29b79882011-05-31 14:20:54 -03003646
3647 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003648
Marcel Holtmann880be4e2013-10-13 07:25:18 -07003649 /* The advertising parameters for own address type
3650 * define which source address and source address
3651 * type this connections has.
3652 */
3653 if (bacmp(&conn->src, BDADDR_ANY)) {
3654 conn->src_type = ADDR_LE_DEV_PUBLIC;
3655 } else {
3656 bacpy(&conn->src, &hdev->static_addr);
3657 conn->src_type = ADDR_LE_DEV_RANDOM;
3658 }
3659
Andre Guedesb9b343d2012-07-27 15:10:11 -03003660 if (ev->role == LE_CONN_ROLE_MASTER) {
3661 conn->out = true;
3662 conn->link_mode |= HCI_LM_MASTER;
3663 }
Ville Tervob62f3282011-02-10 22:38:50 -03003664 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003665
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003666 /* Ensure that the hci_conn contains the identity address type
3667 * regardless of which address the connection was made with.
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003668 */
Johan Hedberga1f4c312014-02-27 14:05:41 +02003669 hci_copy_identity_address(hdev, &conn->src, &conn->src_type);
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003670
Marcel Holtmannedb4b462014-02-18 15:13:43 -08003671 /* Lookup the identity address from the stored connection
3672 * address and address type.
3673 *
3674 * When establishing connections to an identity address, the
3675 * connection procedure will store the resolvable random
3676 * address first. Now if it can be converted back into the
3677 * identity address, start using the identity address from
3678 * now on.
3679 */
3680 irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003681 if (irk) {
3682 bacpy(&conn->dst, &irk->bdaddr);
3683 conn->dst_type = irk->addr_type;
3684 }
3685
Andre Guedescd17dec2012-07-27 15:10:16 -03003686 if (ev->status) {
Andre Guedes06c053f2014-02-26 20:21:41 -03003687 hci_le_conn_failed(conn, ev->status);
Andre Guedescd17dec2012-07-27 15:10:16 -03003688 goto unlock;
3689 }
3690
Johan Hedbergb644ba32012-01-17 21:48:47 +02003691 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Marcel Holtmann01fdb0f2014-02-18 14:22:19 -08003692 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003693 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003694
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003695 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003696 conn->handle = __le16_to_cpu(ev->handle);
3697 conn->state = BT_CONNECTED;
3698
Jukka Rissanen18722c22013-12-11 17:05:37 +02003699 if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
3700 set_bit(HCI_CONN_6LOWPAN, &conn->flags);
3701
Ville Tervofcd89c02011-02-10 22:38:47 -03003702 hci_conn_add_sysfs(conn);
3703
3704 hci_proto_connect_cfm(conn, ev->status);
3705
Andre Guedesa4790db2014-02-26 20:21:47 -03003706 hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type);
3707
Ville Tervofcd89c02011-02-10 22:38:47 -03003708unlock:
3709 hci_dev_unlock(hdev);
3710}
3711
Andre Guedesa4790db2014-02-26 20:21:47 -03003712/* This function requires the caller holds hdev->lock */
3713static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
3714 u8 addr_type)
3715{
3716 struct hci_conn *conn;
Andre Guedes5b906a82014-02-26 20:21:53 -03003717 struct smp_irk *irk;
3718
3719 /* If this is a resolvable address, we should resolve it and then
3720 * update address and address type variables.
3721 */
3722 irk = hci_get_irk(hdev, addr, addr_type);
3723 if (irk) {
3724 addr = &irk->bdaddr;
3725 addr_type = irk->addr_type;
3726 }
Andre Guedesa4790db2014-02-26 20:21:47 -03003727
3728 if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
3729 return;
3730
3731 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
3732 HCI_AT_NO_BONDING);
3733 if (!IS_ERR(conn))
3734 return;
3735
3736 switch (PTR_ERR(conn)) {
3737 case -EBUSY:
3738 /* If hci_connect() returns -EBUSY it means there is already
3739 * an LE connection attempt going on. Since controllers don't
3740 * support more than one connection attempt at the time, we
3741 * don't consider this an error case.
3742 */
3743 break;
3744 default:
3745 BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
3746 }
3747}
3748
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003749static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003750{
Andre Guedese95beb42011-09-26 20:48:35 -03003751 u8 num_reports = skb->data[0];
3752 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003753 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003754
Andre Guedesa4790db2014-02-26 20:21:47 -03003755 hci_dev_lock(hdev);
3756
Andre Guedese95beb42011-09-26 20:48:35 -03003757 while (num_reports--) {
3758 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003759
Andre Guedesa4790db2014-02-26 20:21:47 -03003760 if (ev->evt_type == LE_ADV_IND ||
3761 ev->evt_type == LE_ADV_DIRECT_IND)
3762 check_pending_le_conn(hdev, &ev->bdaddr,
3763 ev->bdaddr_type);
3764
Andre Guedes3c9e9192012-01-10 18:20:50 -03003765 rssi = ev->data[ev->length];
3766 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003767 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003768
Andre Guedese95beb42011-09-26 20:48:35 -03003769 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003770 }
Andre Guedesa4790db2014-02-26 20:21:47 -03003771
3772 hci_dev_unlock(hdev);
Andre Guedes9aa04c92011-05-26 16:23:51 -03003773}
3774
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003775static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003776{
3777 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3778 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003779 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003780 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003781 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003782
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003783 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003784
3785 hci_dev_lock(hdev);
3786
3787 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003788 if (conn == NULL)
3789 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003790
Johan Hedberg98a0b842014-01-30 19:40:00 -08003791 ltk = hci_find_ltk(hdev, ev->ediv, ev->random, conn->out);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003792 if (ltk == NULL)
3793 goto not_found;
3794
3795 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003796 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003797
3798 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03003799 conn->pending_sec_level = BT_SECURITY_HIGH;
3800 else
3801 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003802
Andre Guedes89cbb4d2013-07-31 16:25:29 -03003803 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003804
3805 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3806
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003807 if (ltk->type & HCI_SMP_STK) {
3808 list_del(&ltk->list);
3809 kfree(ltk);
3810 }
3811
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003812 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003813
3814 return;
3815
3816not_found:
3817 neg.handle = ev->handle;
3818 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3819 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003820}
3821
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003822static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003823{
3824 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3825
3826 skb_pull(skb, sizeof(*le_ev));
3827
3828 switch (le_ev->subevent) {
3829 case HCI_EV_LE_CONN_COMPLETE:
3830 hci_le_conn_complete_evt(hdev, skb);
3831 break;
3832
Andre Guedes9aa04c92011-05-26 16:23:51 -03003833 case HCI_EV_LE_ADVERTISING_REPORT:
3834 hci_le_adv_report_evt(hdev, skb);
3835 break;
3836
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003837 case HCI_EV_LE_LTK_REQ:
3838 hci_le_ltk_request_evt(hdev, skb);
3839 break;
3840
Ville Tervofcd89c02011-02-10 22:38:47 -03003841 default:
3842 break;
3843 }
3844}
3845
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003846static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3847{
3848 struct hci_ev_channel_selected *ev = (void *) skb->data;
3849 struct hci_conn *hcon;
3850
3851 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3852
3853 skb_pull(skb, sizeof(*ev));
3854
3855 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3856 if (!hcon)
3857 return;
3858
3859 amp_read_loc_assoc_final_data(hdev, hcon);
3860}
3861
Linus Torvalds1da177e2005-04-16 15:20:36 -07003862void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3863{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003864 struct hci_event_hdr *hdr = (void *) skb->data;
3865 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003866
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003867 hci_dev_lock(hdev);
3868
3869 /* Received events are (currently) only needed when a request is
3870 * ongoing so avoid unnecessary memory allocation.
3871 */
3872 if (hdev->req_status == HCI_REQ_PEND) {
3873 kfree_skb(hdev->recv_evt);
3874 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3875 }
3876
3877 hci_dev_unlock(hdev);
3878
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3880
Johan Hedberg02350a72013-04-03 21:50:29 +03003881 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02003882 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
3883 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03003884
3885 hci_req_cmd_complete(hdev, opcode, 0);
3886 }
3887
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003888 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003889 case HCI_EV_INQUIRY_COMPLETE:
3890 hci_inquiry_complete_evt(hdev, skb);
3891 break;
3892
3893 case HCI_EV_INQUIRY_RESULT:
3894 hci_inquiry_result_evt(hdev, skb);
3895 break;
3896
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003897 case HCI_EV_CONN_COMPLETE:
3898 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003899 break;
3900
Linus Torvalds1da177e2005-04-16 15:20:36 -07003901 case HCI_EV_CONN_REQUEST:
3902 hci_conn_request_evt(hdev, skb);
3903 break;
3904
Linus Torvalds1da177e2005-04-16 15:20:36 -07003905 case HCI_EV_DISCONN_COMPLETE:
3906 hci_disconn_complete_evt(hdev, skb);
3907 break;
3908
Linus Torvalds1da177e2005-04-16 15:20:36 -07003909 case HCI_EV_AUTH_COMPLETE:
3910 hci_auth_complete_evt(hdev, skb);
3911 break;
3912
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003913 case HCI_EV_REMOTE_NAME:
3914 hci_remote_name_evt(hdev, skb);
3915 break;
3916
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917 case HCI_EV_ENCRYPT_CHANGE:
3918 hci_encrypt_change_evt(hdev, skb);
3919 break;
3920
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003921 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3922 hci_change_link_key_complete_evt(hdev, skb);
3923 break;
3924
3925 case HCI_EV_REMOTE_FEATURES:
3926 hci_remote_features_evt(hdev, skb);
3927 break;
3928
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003929 case HCI_EV_CMD_COMPLETE:
3930 hci_cmd_complete_evt(hdev, skb);
3931 break;
3932
3933 case HCI_EV_CMD_STATUS:
3934 hci_cmd_status_evt(hdev, skb);
3935 break;
3936
3937 case HCI_EV_ROLE_CHANGE:
3938 hci_role_change_evt(hdev, skb);
3939 break;
3940
3941 case HCI_EV_NUM_COMP_PKTS:
3942 hci_num_comp_pkts_evt(hdev, skb);
3943 break;
3944
3945 case HCI_EV_MODE_CHANGE:
3946 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003947 break;
3948
3949 case HCI_EV_PIN_CODE_REQ:
3950 hci_pin_code_request_evt(hdev, skb);
3951 break;
3952
3953 case HCI_EV_LINK_KEY_REQ:
3954 hci_link_key_request_evt(hdev, skb);
3955 break;
3956
3957 case HCI_EV_LINK_KEY_NOTIFY:
3958 hci_link_key_notify_evt(hdev, skb);
3959 break;
3960
3961 case HCI_EV_CLOCK_OFFSET:
3962 hci_clock_offset_evt(hdev, skb);
3963 break;
3964
Marcel Holtmanna8746412008-07-14 20:13:46 +02003965 case HCI_EV_PKT_TYPE_CHANGE:
3966 hci_pkt_type_change_evt(hdev, skb);
3967 break;
3968
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003969 case HCI_EV_PSCAN_REP_MODE:
3970 hci_pscan_rep_mode_evt(hdev, skb);
3971 break;
3972
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003973 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3974 hci_inquiry_result_with_rssi_evt(hdev, skb);
3975 break;
3976
3977 case HCI_EV_REMOTE_EXT_FEATURES:
3978 hci_remote_ext_features_evt(hdev, skb);
3979 break;
3980
3981 case HCI_EV_SYNC_CONN_COMPLETE:
3982 hci_sync_conn_complete_evt(hdev, skb);
3983 break;
3984
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003985 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3986 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003987 break;
3988
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003989 case HCI_EV_KEY_REFRESH_COMPLETE:
3990 hci_key_refresh_complete_evt(hdev, skb);
3991 break;
3992
Marcel Holtmann04936842008-07-14 20:13:48 +02003993 case HCI_EV_IO_CAPA_REQUEST:
3994 hci_io_capa_request_evt(hdev, skb);
3995 break;
3996
Johan Hedberg03b555e2011-01-04 15:40:05 +02003997 case HCI_EV_IO_CAPA_REPLY:
3998 hci_io_capa_reply_evt(hdev, skb);
3999 break;
4000
Johan Hedberga5c29682011-02-19 12:05:57 -03004001 case HCI_EV_USER_CONFIRM_REQUEST:
4002 hci_user_confirm_request_evt(hdev, skb);
4003 break;
4004
Brian Gix1143d452011-11-23 08:28:34 -08004005 case HCI_EV_USER_PASSKEY_REQUEST:
4006 hci_user_passkey_request_evt(hdev, skb);
4007 break;
4008
Johan Hedberg92a25252012-09-06 18:39:26 +03004009 case HCI_EV_USER_PASSKEY_NOTIFY:
4010 hci_user_passkey_notify_evt(hdev, skb);
4011 break;
4012
4013 case HCI_EV_KEYPRESS_NOTIFY:
4014 hci_keypress_notify_evt(hdev, skb);
4015 break;
4016
Marcel Holtmann04936842008-07-14 20:13:48 +02004017 case HCI_EV_SIMPLE_PAIR_COMPLETE:
4018 hci_simple_pair_complete_evt(hdev, skb);
4019 break;
4020
Marcel Holtmann41a96212008-07-14 20:13:48 +02004021 case HCI_EV_REMOTE_HOST_FEATURES:
4022 hci_remote_host_features_evt(hdev, skb);
4023 break;
4024
Ville Tervofcd89c02011-02-10 22:38:47 -03004025 case HCI_EV_LE_META:
4026 hci_le_meta_evt(hdev, skb);
4027 break;
4028
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004029 case HCI_EV_CHANNEL_SELECTED:
4030 hci_chan_selected_evt(hdev, skb);
4031 break;
4032
Szymon Janc2763eda2011-03-22 13:12:22 +01004033 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
4034 hci_remote_oob_data_request_evt(hdev, skb);
4035 break;
4036
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03004037 case HCI_EV_PHY_LINK_COMPLETE:
4038 hci_phy_link_complete_evt(hdev, skb);
4039 break;
4040
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004041 case HCI_EV_LOGICAL_LINK_COMPLETE:
4042 hci_loglink_complete_evt(hdev, skb);
4043 break;
4044
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02004045 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
4046 hci_disconn_loglink_complete_evt(hdev, skb);
4047 break;
4048
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02004049 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
4050 hci_disconn_phylink_complete_evt(hdev, skb);
4051 break;
4052
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02004053 case HCI_EV_NUM_COMP_BLOCKS:
4054 hci_num_comp_blocks_evt(hdev, skb);
4055 break;
4056
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004057 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03004058 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004059 break;
4060 }
4061
4062 kfree_skb(skb);
4063 hdev->stat.evt_rx++;
4064}