blob: e3335b03c9923145a1b92216f3958bc660f07b03 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <asm/unaligned.h>
28
29#include <net/bluetooth/bluetooth.h>
30#include <net/bluetooth/hci_core.h>
Mikel Astizf0d6a0e2012-08-09 09:52:30 +020031#include <net/bluetooth/mgmt.h>
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070032
Marcel Holtmann70247282013-10-10 14:54:15 -070033#include "a2mp.h"
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070034#include "amp.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
Linus Torvalds1da177e2005-04-16 15:20:36 -070036/* Handle HCI Event packets */
37
Marcel Holtmanna9de9242007-10-20 13:33:56 +020038static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070039{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020040 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030042 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
Andre Guedes82f47852013-04-30 15:29:34 -030044 if (status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020045 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
Andre Guedes89352e72011-11-04 14:16:53 -030047 clear_bit(HCI_INQUIRY, &hdev->flags);
Andre Guedes3e13fa12013-03-27 20:04:56 -030048 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
49 wake_up_bit(&hdev->flags, HCI_INQUIRY);
Andre Guedes89352e72011-11-04 14:16:53 -030050
Marcel Holtmanna9de9242007-10-20 13:33:56 +020051 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070052}
53
Andre Guedes4d934832012-03-21 00:03:35 -030054static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
55{
56 __u8 status = *((__u8 *) skb->data);
57
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030058 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesae854a72012-03-21 00:03:36 -030059
60 if (status)
61 return;
62
63 set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
Andre Guedes4d934832012-03-21 00:03:35 -030064}
65
Marcel Holtmanna9de9242007-10-20 13:33:56 +020066static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020068 __u8 status = *((__u8 *) skb->data);
69
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030070 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020071
72 if (status)
73 return;
74
Andre Guedesae854a72012-03-21 00:03:36 -030075 clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
76
Marcel Holtmanna9de9242007-10-20 13:33:56 +020077 hci_conn_check_pending(hdev);
78}
79
Gustavo Padovan807deac2012-05-17 00:36:24 -030080static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
81 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020082{
83 BT_DBG("%s", hdev->name);
84}
85
86static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
87{
88 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030091 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
Marcel Holtmanna9de9242007-10-20 13:33:56 +020093 if (rp->status)
94 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
Marcel Holtmanna9de9242007-10-20 13:33:56 +020096 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Marcel Holtmanna9de9242007-10-20 13:33:56 +020098 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
99 if (conn) {
100 if (rp->role)
101 conn->link_mode &= ~HCI_LM_MASTER;
102 else
103 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200105
106 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107}
108
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200109static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
110{
111 struct hci_rp_read_link_policy *rp = (void *) skb->data;
112 struct hci_conn *conn;
113
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300114 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200115
116 if (rp->status)
117 return;
118
119 hci_dev_lock(hdev);
120
121 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
122 if (conn)
123 conn->link_policy = __le16_to_cpu(rp->policy);
124
125 hci_dev_unlock(hdev);
126}
127
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200128static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200130 struct hci_rp_write_link_policy *rp = (void *) skb->data;
131 struct hci_conn *conn;
132 void *sent;
133
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300134 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200135
136 if (rp->status)
137 return;
138
139 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
140 if (!sent)
141 return;
142
143 hci_dev_lock(hdev);
144
145 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200146 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700147 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200148
149 hci_dev_unlock(hdev);
150}
151
Gustavo Padovan807deac2012-05-17 00:36:24 -0300152static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
153 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200154{
155 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
156
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300157 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200158
159 if (rp->status)
160 return;
161
162 hdev->link_policy = __le16_to_cpu(rp->policy);
163}
164
Gustavo Padovan807deac2012-05-17 00:36:24 -0300165static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
166 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200167{
168 __u8 status = *((__u8 *) skb->data);
169 void *sent;
170
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300171 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200172
173 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
174 if (!sent)
175 return;
176
177 if (!status)
178 hdev->link_policy = get_unaligned_le16(sent);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200179}
180
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200181static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
182{
183 __u8 status = *((__u8 *) skb->data);
184
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300185 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200186
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300187 clear_bit(HCI_RESET, &hdev->flags);
188
Johan Hedberga297e972012-02-21 17:55:47 +0200189 /* Reset all non-persistent flags */
Johan Hedberg2cc6fb02013-03-15 17:06:57 -0500190 hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
Andre Guedes69775ff2012-02-23 16:50:05 +0200191
192 hdev->discovery.state = DISCOVERY_STOPPED;
Johan Hedbergbbaf4442012-11-08 01:22:59 +0100193 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
194 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100195
196 memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
197 hdev->adv_data_len = 0;
Marcel Holtmannf8e808b2013-10-16 00:16:47 -0700198
199 memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
200 hdev->scan_rsp_data_len = 0;
Marcel Holtmann06f5b772013-10-19 07:09:11 -0700201
202 hdev->ssp_debug_mode = 0;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200203}
204
205static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
206{
207 __u8 status = *((__u8 *) skb->data);
208 void *sent;
209
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300210 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200211
212 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
213 if (!sent)
214 return;
215
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200216 hci_dev_lock(hdev);
217
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200218 if (test_bit(HCI_MGMT, &hdev->dev_flags))
219 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200220 else if (!status)
221 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200222
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200223 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200224}
225
226static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
227{
228 struct hci_rp_read_local_name *rp = (void *) skb->data;
229
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300230 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200231
232 if (rp->status)
233 return;
234
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200235 if (test_bit(HCI_SETUP, &hdev->dev_flags))
236 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200237}
238
239static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
240{
241 __u8 status = *((__u8 *) skb->data);
242 void *sent;
243
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300244 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200245
246 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
247 if (!sent)
248 return;
249
250 if (!status) {
251 __u8 param = *((__u8 *) sent);
252
253 if (param == AUTH_ENABLED)
254 set_bit(HCI_AUTH, &hdev->flags);
255 else
256 clear_bit(HCI_AUTH, &hdev->flags);
257 }
258
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200259 if (test_bit(HCI_MGMT, &hdev->dev_flags))
260 mgmt_auth_enable_complete(hdev, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200261}
262
263static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
264{
265 __u8 status = *((__u8 *) skb->data);
266 void *sent;
267
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300268 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200269
270 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
271 if (!sent)
272 return;
273
274 if (!status) {
275 __u8 param = *((__u8 *) sent);
276
277 if (param)
278 set_bit(HCI_ENCRYPT, &hdev->flags);
279 else
280 clear_bit(HCI_ENCRYPT, &hdev->flags);
281 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200282}
283
284static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
285{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200286 __u8 param, status = *((__u8 *) skb->data);
287 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200288 void *sent;
289
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300290 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200291
292 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
293 if (!sent)
294 return;
295
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200296 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200297
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200298 hci_dev_lock(hdev);
299
Mikel Astizfa1bd912012-08-09 09:52:29 +0200300 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200301 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200302 hdev->discov_timeout = 0;
303 goto done;
304 }
305
Johan Hedberg0663ca22013-10-02 13:43:14 +0300306 /* We need to ensure that we set this back on if someone changed
307 * the scan mode through a raw HCI socket.
308 */
309 set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
310
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200311 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
312 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200313
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200314 if (param & SCAN_INQUIRY) {
315 set_bit(HCI_ISCAN, &hdev->flags);
316 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200317 mgmt_discoverable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200318 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200319 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200320
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200321 if (param & SCAN_PAGE) {
322 set_bit(HCI_PSCAN, &hdev->flags);
323 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200324 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200325 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200326 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200327
328done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200329 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200330}
331
332static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
333{
334 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
335
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300336 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200337
338 if (rp->status)
339 return;
340
341 memcpy(hdev->dev_class, rp->dev_class, 3);
342
343 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300344 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200345}
346
347static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
348{
349 __u8 status = *((__u8 *) skb->data);
350 void *sent;
351
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300352 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200353
354 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
355 if (!sent)
356 return;
357
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100358 hci_dev_lock(hdev);
359
360 if (status == 0)
361 memcpy(hdev->dev_class, sent, 3);
362
363 if (test_bit(HCI_MGMT, &hdev->dev_flags))
364 mgmt_set_class_of_dev_complete(hdev, sent, status);
365
366 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200367}
368
369static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
370{
371 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200373
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300374 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200375
376 if (rp->status)
377 return;
378
379 setting = __le16_to_cpu(rp->voice_setting);
380
Marcel Holtmannf383f272008-07-14 20:13:47 +0200381 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200382 return;
383
384 hdev->voice_setting = setting;
385
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300386 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200387
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200388 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200390}
391
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300392static void hci_cc_write_voice_setting(struct hci_dev *hdev,
393 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200394{
395 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200396 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 void *sent;
398
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300399 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
Marcel Holtmannf383f272008-07-14 20:13:47 +0200401 if (status)
402 return;
403
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200404 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
405 if (!sent)
406 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
Marcel Holtmannf383f272008-07-14 20:13:47 +0200408 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410 if (hdev->voice_setting == setting)
411 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
Marcel Holtmannf383f272008-07-14 20:13:47 +0200413 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300415 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200416
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200417 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200418 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419}
420
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -0700421static void hci_cc_read_num_supported_iac(struct hci_dev *hdev,
422 struct sk_buff *skb)
423{
424 struct hci_rp_read_num_supported_iac *rp = (void *) skb->data;
425
426 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
427
428 if (rp->status)
429 return;
430
431 hdev->num_iac = rp->num_iac;
432
433 BT_DBG("%s num iac %d", hdev->name, hdev->num_iac);
434}
435
Marcel Holtmann333140b2008-07-14 20:13:48 +0200436static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
437{
438 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300439 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200440
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300441 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200442
Marcel Holtmann333140b2008-07-14 20:13:48 +0200443 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
444 if (!sent)
445 return;
446
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300447 if (!status) {
448 if (sent->mode)
Johan Hedbergcad718e2013-04-17 15:00:51 +0300449 hdev->features[1][0] |= LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300450 else
Johan Hedbergcad718e2013-04-17 15:00:51 +0300451 hdev->features[1][0] &= ~LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300452 }
453
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200454 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300455 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200456 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300457 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200458 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
459 else
460 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
461 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200462}
463
Marcel Holtmanneac83dc2014-01-10 02:07:23 -0800464static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb)
465{
466 u8 status = *((u8 *) skb->data);
467 struct hci_cp_write_sc_support *sent;
468
469 BT_DBG("%s status 0x%2.2x", hdev->name, status);
470
471 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
472 if (!sent)
473 return;
474
475 if (!status) {
476 if (sent->support)
477 hdev->features[1][0] |= LMP_HOST_SC;
478 else
479 hdev->features[1][0] &= ~LMP_HOST_SC;
480 }
481
482 if (test_bit(HCI_MGMT, &hdev->dev_flags))
483 mgmt_sc_enable_complete(hdev, sent->support, status);
484 else if (!status) {
485 if (sent->support)
486 set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
487 else
488 clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
489 }
490}
491
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200492static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
493{
494 struct hci_rp_read_local_version *rp = (void *) skb->data;
495
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300496 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200497
498 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200499 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200500
Marcel Holtmann0d5551f2013-10-18 12:04:50 -0700501 if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
502 hdev->hci_ver = rp->hci_ver;
503 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
504 hdev->lmp_ver = rp->lmp_ver;
505 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
506 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
507 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200508}
509
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300510static void hci_cc_read_local_commands(struct hci_dev *hdev,
511 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200512{
513 struct hci_rp_read_local_commands *rp = (void *) skb->data;
514
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300515 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200516
Marcel Holtmann6a070e62013-10-31 04:54:33 -0700517 if (rp->status)
518 return;
519
520 if (test_bit(HCI_SETUP, &hdev->dev_flags))
Johan Hedberg2177bab2013-03-05 20:37:43 +0200521 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200522}
523
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300524static void hci_cc_read_local_features(struct hci_dev *hdev,
525 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200526{
527 struct hci_rp_read_local_features *rp = (void *) skb->data;
528
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300529 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200530
531 if (rp->status)
532 return;
533
534 memcpy(hdev->features, rp->features, 8);
535
536 /* Adjust default settings according to features
537 * supported by device. */
538
Johan Hedbergcad718e2013-04-17 15:00:51 +0300539 if (hdev->features[0][0] & LMP_3SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200540 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
541
Johan Hedbergcad718e2013-04-17 15:00:51 +0300542 if (hdev->features[0][0] & LMP_5SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200543 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
544
Johan Hedbergcad718e2013-04-17 15:00:51 +0300545 if (hdev->features[0][1] & LMP_HV2) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200546 hdev->pkt_type |= (HCI_HV2);
547 hdev->esco_type |= (ESCO_HV2);
548 }
549
Johan Hedbergcad718e2013-04-17 15:00:51 +0300550 if (hdev->features[0][1] & LMP_HV3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200551 hdev->pkt_type |= (HCI_HV3);
552 hdev->esco_type |= (ESCO_HV3);
553 }
554
Andre Guedes45db810f2012-07-24 15:03:49 -0300555 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200556 hdev->esco_type |= (ESCO_EV3);
557
Johan Hedbergcad718e2013-04-17 15:00:51 +0300558 if (hdev->features[0][4] & LMP_EV4)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200559 hdev->esco_type |= (ESCO_EV4);
560
Johan Hedbergcad718e2013-04-17 15:00:51 +0300561 if (hdev->features[0][4] & LMP_EV5)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200562 hdev->esco_type |= (ESCO_EV5);
563
Johan Hedbergcad718e2013-04-17 15:00:51 +0300564 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100565 hdev->esco_type |= (ESCO_2EV3);
566
Johan Hedbergcad718e2013-04-17 15:00:51 +0300567 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100568 hdev->esco_type |= (ESCO_3EV3);
569
Johan Hedbergcad718e2013-04-17 15:00:51 +0300570 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100571 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200572}
573
Andre Guedes971e3a42011-06-30 19:20:52 -0300574static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300575 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300576{
577 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
578
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300579 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300580
581 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200582 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300583
Marcel Holtmann57af75a2013-10-18 12:04:47 -0700584 if (hdev->max_page < rp->max_page)
585 hdev->max_page = rp->max_page;
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300586
Johan Hedbergcad718e2013-04-17 15:00:51 +0300587 if (rp->page < HCI_MAX_PAGES)
588 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300589}
590
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200591static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300592 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200593{
594 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
595
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300596 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200597
Johan Hedberg42c6b122013-03-05 20:37:49 +0200598 if (!rp->status)
599 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200600}
601
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200602static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
603{
604 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
605
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300606 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200607
608 if (rp->status)
609 return;
610
611 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
612 hdev->sco_mtu = rp->sco_mtu;
613 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
614 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
615
616 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
617 hdev->sco_mtu = 64;
618 hdev->sco_pkts = 8;
619 }
620
621 hdev->acl_cnt = hdev->acl_pkts;
622 hdev->sco_cnt = hdev->sco_pkts;
623
Gustavo Padovan807deac2012-05-17 00:36:24 -0300624 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
625 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200626}
627
628static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
629{
630 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
631
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300632 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200633
634 if (!rp->status)
635 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200636}
637
Johan Hedbergf332ec62013-03-15 17:07:11 -0500638static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
639 struct sk_buff *skb)
640{
641 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
642
643 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
644
645 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
646 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
647 hdev->page_scan_window = __le16_to_cpu(rp->window);
648 }
649}
650
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500651static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
652 struct sk_buff *skb)
653{
654 u8 status = *((u8 *) skb->data);
655 struct hci_cp_write_page_scan_activity *sent;
656
657 BT_DBG("%s status 0x%2.2x", hdev->name, status);
658
659 if (status)
660 return;
661
662 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
663 if (!sent)
664 return;
665
666 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
667 hdev->page_scan_window = __le16_to_cpu(sent->window);
668}
669
Johan Hedbergf332ec62013-03-15 17:07:11 -0500670static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
671 struct sk_buff *skb)
672{
673 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
674
675 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
676
677 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
678 hdev->page_scan_type = rp->type;
679}
680
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500681static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
682 struct sk_buff *skb)
683{
684 u8 status = *((u8 *) skb->data);
685 u8 *type;
686
687 BT_DBG("%s status 0x%2.2x", hdev->name, status);
688
689 if (status)
690 return;
691
692 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
693 if (type)
694 hdev->page_scan_type = *type;
695}
696
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200697static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300698 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200699{
700 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
701
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300702 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200703
704 if (rp->status)
705 return;
706
707 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
708 hdev->block_len = __le16_to_cpu(rp->block_len);
709 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
710
711 hdev->block_cnt = hdev->num_blocks;
712
713 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300714 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200715}
716
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300717static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300718 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300719{
720 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
721
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300722 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300723
724 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300725 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300726
727 hdev->amp_status = rp->amp_status;
728 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
729 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
730 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
731 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
732 hdev->amp_type = rp->amp_type;
733 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
734 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
735 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
736 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
737
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300738a2mp_rsp:
739 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300740}
741
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300742static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
743 struct sk_buff *skb)
744{
745 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
746 struct amp_assoc *assoc = &hdev->loc_assoc;
747 size_t rem_len, frag_len;
748
749 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
750
751 if (rp->status)
752 goto a2mp_rsp;
753
754 frag_len = skb->len - sizeof(*rp);
755 rem_len = __le16_to_cpu(rp->rem_len);
756
757 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300758 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300759
760 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
761 assoc->offset += frag_len;
762
763 /* Read other fragments */
764 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
765
766 return;
767 }
768
769 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
770 assoc->len = assoc->offset + rem_len;
771 assoc->offset = 0;
772
773a2mp_rsp:
774 /* Send A2MP Rsp when all fragments are received */
775 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300776 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300777}
778
Johan Hedbergd5859e22011-01-25 01:19:58 +0200779static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300780 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200781{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700782 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200783
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300784 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200785
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700786 if (!rp->status)
787 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200788}
789
Johan Hedberg980e1a52011-01-22 06:10:07 +0200790static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
791{
792 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
793 struct hci_cp_pin_code_reply *cp;
794 struct hci_conn *conn;
795
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300796 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200797
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200798 hci_dev_lock(hdev);
799
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200800 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200801 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200802
Mikel Astizfa1bd912012-08-09 09:52:29 +0200803 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200804 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200805
806 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
807 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200808 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200809
810 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
811 if (conn)
812 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200813
814unlock:
815 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200816}
817
818static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
819{
820 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
821
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300822 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200823
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200824 hci_dev_lock(hdev);
825
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200826 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200827 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300828 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200829
830 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200831}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200832
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300833static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
834 struct sk_buff *skb)
835{
836 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
837
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300838 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300839
840 if (rp->status)
841 return;
842
843 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
844 hdev->le_pkts = rp->le_max_pkt;
845
846 hdev->le_cnt = hdev->le_pkts;
847
848 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300849}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200850
Johan Hedberg60e77322013-01-22 14:01:59 +0200851static void hci_cc_le_read_local_features(struct hci_dev *hdev,
852 struct sk_buff *skb)
853{
854 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
855
856 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
857
858 if (!rp->status)
859 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200860}
861
Johan Hedberg8fa19092012-10-19 20:57:49 +0300862static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
863 struct sk_buff *skb)
864{
865 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
866
867 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
868
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500869 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300870 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300871}
872
Johan Hedberga5c29682011-02-19 12:05:57 -0300873static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
874{
875 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
876
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300877 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300878
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200879 hci_dev_lock(hdev);
880
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200881 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300882 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
883 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200884
885 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300886}
887
888static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300889 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300890{
891 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
892
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300893 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300894
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200895 hci_dev_lock(hdev);
896
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200897 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200898 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300899 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200900
901 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300902}
903
Brian Gix1143d452011-11-23 08:28:34 -0800904static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
905{
906 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
907
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300908 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800909
910 hci_dev_lock(hdev);
911
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200912 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200913 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300914 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800915
916 hci_dev_unlock(hdev);
917}
918
919static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300920 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800921{
922 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
923
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300924 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800925
926 hci_dev_lock(hdev);
927
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200928 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800929 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300930 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800931
932 hci_dev_unlock(hdev);
933}
934
Marcel Holtmann4d2d2792014-01-10 02:07:26 -0800935static void hci_cc_read_local_oob_data(struct hci_dev *hdev,
936 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100937{
938 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
939
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300940 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100941
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200942 hci_dev_lock(hdev);
Marcel Holtmann4d2d2792014-01-10 02:07:26 -0800943 mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->randomizer,
944 NULL, NULL, rp->status);
945 hci_dev_unlock(hdev);
946}
947
948static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev,
949 struct sk_buff *skb)
950{
951 struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data;
952
953 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
954
955 hci_dev_lock(hdev);
956 mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->randomizer192,
957 rp->hash256, rp->randomizer256,
958 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200959 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100960}
961
Marcel Holtmann7a4cd512014-02-19 19:52:13 -0800962
963static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb)
964{
965 __u8 status = *((__u8 *) skb->data);
966 bdaddr_t *sent;
967
968 BT_DBG("%s status 0x%2.2x", hdev->name, status);
969
970 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
971 if (!sent)
972 return;
973
974 hci_dev_lock(hdev);
975
976 if (!status)
977 bacpy(&hdev->random_addr, sent);
978
979 hci_dev_unlock(hdev);
980}
981
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100982static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
983{
984 __u8 *sent, status = *((__u8 *) skb->data);
985
986 BT_DBG("%s status 0x%2.2x", hdev->name, status);
987
988 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
989 if (!sent)
990 return;
991
992 hci_dev_lock(hdev);
993
Johan Hedberg778b2352014-02-24 14:52:17 +0200994 if (!status)
995 mgmt_advertising(hdev, *sent);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100996
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500997 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100998}
999
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001000static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001001 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001002{
1003 struct hci_cp_le_set_scan_enable *cp;
1004 __u8 status = *((__u8 *) skb->data);
1005
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001006 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001007
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001008 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1009 if (!cp)
1010 return;
1011
Andre Guedes3fd319b2013-04-30 15:29:36 -03001012 if (status)
1013 return;
1014
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001015 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -03001016 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -03001017 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001018 break;
1019
Andre Guedes76a388b2013-04-04 20:21:02 -03001020 case LE_SCAN_DISABLE:
Johan Hedberg317ac8c2014-02-28 20:26:12 +02001021 /* Cancel this timer so that we don't try to disable scanning
1022 * when it's already disabled.
1023 */
1024 cancel_delayed_work(&hdev->le_scan_disable);
1025
Andre Guedesd23264a2011-11-25 20:53:38 -03001026 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001027 break;
1028
1029 default:
1030 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1031 break;
Andre Guedes35815082011-05-26 16:23:53 -03001032 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001033}
1034
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001035static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
1036 struct sk_buff *skb)
1037{
1038 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
1039
1040 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
1041
1042 if (!rp->status)
1043 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001044}
1045
Marcel Holtmann0f36b582014-02-27 20:37:31 -08001046static void hci_cc_le_clear_white_list(struct hci_dev *hdev,
1047 struct sk_buff *skb)
1048{
1049 __u8 status = *((__u8 *) skb->data);
1050
1051 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1052
1053 if (!status)
1054 hci_white_list_clear(hdev);
1055}
1056
1057static void hci_cc_le_add_to_white_list(struct hci_dev *hdev,
1058 struct sk_buff *skb)
1059{
1060 struct hci_cp_le_add_to_white_list *sent;
1061 __u8 status = *((__u8 *) skb->data);
1062
1063 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1064
1065 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST);
1066 if (!sent)
1067 return;
1068
1069 if (!status)
1070 hci_white_list_add(hdev, &sent->bdaddr, sent->bdaddr_type);
1071}
1072
1073static void hci_cc_le_del_from_white_list(struct hci_dev *hdev,
1074 struct sk_buff *skb)
1075{
1076 struct hci_cp_le_del_from_white_list *sent;
1077 __u8 status = *((__u8 *) skb->data);
1078
1079 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1080
1081 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST);
1082 if (!sent)
1083 return;
1084
1085 if (!status)
1086 hci_white_list_del(hdev, &sent->bdaddr, sent->bdaddr_type);
1087}
1088
Johan Hedberg9b008c02013-01-22 14:02:01 +02001089static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
1090 struct sk_buff *skb)
1091{
1092 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
1093
1094 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1095
1096 if (!rp->status)
1097 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +02001098}
1099
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001100static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1101 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001102{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001103 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001104 __u8 status = *((__u8 *) skb->data);
1105
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001106 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001107
Johan Hedberg06199cf2012-02-22 16:37:11 +02001108 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001109 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001110 return;
1111
Johan Hedberg8f984df2012-02-28 01:07:22 +02001112 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001113 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001114 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001115 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1116 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001117 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001118 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001119 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001120 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001121
1122 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001123 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001124 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001125 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001126 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001127}
1128
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02001129static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
1130{
1131 struct hci_cp_le_set_adv_param *cp;
1132 u8 status = *((u8 *) skb->data);
1133
1134 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1135
1136 if (status)
1137 return;
1138
1139 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM);
1140 if (!cp)
1141 return;
1142
1143 hci_dev_lock(hdev);
1144 hdev->adv_addr_type = cp->own_address_type;
1145 hci_dev_unlock(hdev);
1146}
1147
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001148static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1149 struct sk_buff *skb)
1150{
1151 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1152
1153 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1154 hdev->name, rp->status, rp->phy_handle);
1155
1156 if (rp->status)
1157 return;
1158
1159 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1160}
1161
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001162static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001163{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001164 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001165
1166 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001167 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001168 return;
1169 }
1170
Andre Guedes89352e72011-11-04 14:16:53 -03001171 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001172}
1173
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001174static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001176 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001179 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001180
1181 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182 if (!cp)
1183 return;
1184
1185 hci_dev_lock(hdev);
1186
1187 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1188
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001189 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190
1191 if (status) {
1192 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001193 if (status != 0x0c || conn->attempt > 2) {
1194 conn->state = BT_CLOSED;
1195 hci_proto_connect_cfm(conn, status);
1196 hci_conn_del(conn);
1197 } else
1198 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199 }
1200 } else {
1201 if (!conn) {
1202 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1203 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001204 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 conn->link_mode |= HCI_LM_MASTER;
1206 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001207 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 }
1209 }
1210
1211 hci_dev_unlock(hdev);
1212}
1213
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001214static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001216 struct hci_cp_add_sco *cp;
1217 struct hci_conn *acl, *sco;
1218 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001220 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001221
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001222 if (!status)
1223 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001225 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1226 if (!cp)
1227 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001229 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001231 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001232
1233 hci_dev_lock(hdev);
1234
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001235 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001236 if (acl) {
1237 sco = acl->link;
1238 if (sco) {
1239 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001240
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001241 hci_proto_connect_cfm(sco, status);
1242 hci_conn_del(sco);
1243 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001244 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001245
1246 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247}
1248
Marcel Holtmannf8558552008-07-14 20:13:49 +02001249static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1250{
1251 struct hci_cp_auth_requested *cp;
1252 struct hci_conn *conn;
1253
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001254 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001255
1256 if (!status)
1257 return;
1258
1259 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1260 if (!cp)
1261 return;
1262
1263 hci_dev_lock(hdev);
1264
1265 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1266 if (conn) {
1267 if (conn->state == BT_CONFIG) {
1268 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001269 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001270 }
1271 }
1272
1273 hci_dev_unlock(hdev);
1274}
1275
1276static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1277{
1278 struct hci_cp_set_conn_encrypt *cp;
1279 struct hci_conn *conn;
1280
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001281 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001282
1283 if (!status)
1284 return;
1285
1286 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1287 if (!cp)
1288 return;
1289
1290 hci_dev_lock(hdev);
1291
1292 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1293 if (conn) {
1294 if (conn->state == BT_CONFIG) {
1295 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001296 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001297 }
1298 }
1299
1300 hci_dev_unlock(hdev);
1301}
1302
Johan Hedberg127178d2010-11-18 22:22:29 +02001303static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001304 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001305{
Johan Hedberg392599b2010-11-18 22:22:28 +02001306 if (conn->state != BT_CONFIG || !conn->out)
1307 return 0;
1308
Johan Hedberg765c2a92011-01-19 12:06:52 +05301309 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001310 return 0;
1311
1312 /* Only request authentication for SSP connections or non-SSP
Johan Hedberg264b8b42014-01-08 16:40:39 +02001313 * devices with sec_level MEDIUM or HIGH or if MITM protection
1314 * is requested.
1315 */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001316 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
Johan Hedberg264b8b42014-01-08 16:40:39 +02001317 conn->pending_sec_level != BT_SECURITY_HIGH &&
1318 conn->pending_sec_level != BT_SECURITY_MEDIUM)
Johan Hedberg392599b2010-11-18 22:22:28 +02001319 return 0;
1320
Johan Hedberg392599b2010-11-18 22:22:28 +02001321 return 1;
1322}
1323
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001324static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001325 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001326{
1327 struct hci_cp_remote_name_req cp;
1328
1329 memset(&cp, 0, sizeof(cp));
1330
1331 bacpy(&cp.bdaddr, &e->data.bdaddr);
1332 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1333 cp.pscan_mode = e->data.pscan_mode;
1334 cp.clock_offset = e->data.clock_offset;
1335
1336 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1337}
1338
Johan Hedbergb644ba32012-01-17 21:48:47 +02001339static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001340{
1341 struct discovery_state *discov = &hdev->discovery;
1342 struct inquiry_entry *e;
1343
Johan Hedbergb644ba32012-01-17 21:48:47 +02001344 if (list_empty(&discov->resolve))
1345 return false;
1346
1347 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001348 if (!e)
1349 return false;
1350
Johan Hedbergb644ba32012-01-17 21:48:47 +02001351 if (hci_resolve_name(hdev, e) == 0) {
1352 e->name_state = NAME_PENDING;
1353 return true;
1354 }
1355
1356 return false;
1357}
1358
1359static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001360 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001361{
1362 struct discovery_state *discov = &hdev->discovery;
1363 struct inquiry_entry *e;
1364
1365 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001366 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1367 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001368
1369 if (discov->state == DISCOVERY_STOPPED)
1370 return;
1371
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001372 if (discov->state == DISCOVERY_STOPPING)
1373 goto discov_complete;
1374
1375 if (discov->state != DISCOVERY_RESOLVING)
1376 return;
1377
1378 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001379 /* If the device was not found in a list of found devices names of which
1380 * are pending. there is no need to continue resolving a next name as it
1381 * will be done upon receiving another Remote Name Request Complete
1382 * Event */
1383 if (!e)
1384 return;
1385
1386 list_del(&e->list);
1387 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001388 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001389 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1390 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001391 } else {
1392 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001393 }
1394
Johan Hedbergb644ba32012-01-17 21:48:47 +02001395 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001396 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001397
1398discov_complete:
1399 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1400}
1401
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001402static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1403{
Johan Hedberg127178d2010-11-18 22:22:29 +02001404 struct hci_cp_remote_name_req *cp;
1405 struct hci_conn *conn;
1406
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001407 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001408
1409 /* If successful wait for the name req complete event before
1410 * checking for the need to do authentication */
1411 if (!status)
1412 return;
1413
1414 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1415 if (!cp)
1416 return;
1417
1418 hci_dev_lock(hdev);
1419
1420 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001421
1422 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1423 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1424
Johan Hedberg79c6c702011-04-28 11:28:55 -07001425 if (!conn)
1426 goto unlock;
1427
1428 if (!hci_outgoing_auth_needed(hdev, conn))
1429 goto unlock;
1430
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001431 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001432 struct hci_cp_auth_requested auth_cp;
1433
1434 auth_cp.handle = __cpu_to_le16(conn->handle);
1435 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1436 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001437 }
1438
Johan Hedberg79c6c702011-04-28 11:28:55 -07001439unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001440 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001441}
1442
Marcel Holtmann769be972008-07-14 20:13:49 +02001443static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1444{
1445 struct hci_cp_read_remote_features *cp;
1446 struct hci_conn *conn;
1447
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001448 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001449
1450 if (!status)
1451 return;
1452
1453 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1454 if (!cp)
1455 return;
1456
1457 hci_dev_lock(hdev);
1458
1459 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1460 if (conn) {
1461 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001462 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001463 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001464 }
1465 }
1466
1467 hci_dev_unlock(hdev);
1468}
1469
1470static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1471{
1472 struct hci_cp_read_remote_ext_features *cp;
1473 struct hci_conn *conn;
1474
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001475 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001476
1477 if (!status)
1478 return;
1479
1480 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1481 if (!cp)
1482 return;
1483
1484 hci_dev_lock(hdev);
1485
1486 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1487 if (conn) {
1488 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001489 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001490 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001491 }
1492 }
1493
1494 hci_dev_unlock(hdev);
1495}
1496
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001497static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1498{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001499 struct hci_cp_setup_sync_conn *cp;
1500 struct hci_conn *acl, *sco;
1501 __u16 handle;
1502
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001503 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001504
1505 if (!status)
1506 return;
1507
1508 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1509 if (!cp)
1510 return;
1511
1512 handle = __le16_to_cpu(cp->handle);
1513
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001514 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001515
1516 hci_dev_lock(hdev);
1517
1518 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001519 if (acl) {
1520 sco = acl->link;
1521 if (sco) {
1522 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001523
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001524 hci_proto_connect_cfm(sco, status);
1525 hci_conn_del(sco);
1526 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001527 }
1528
1529 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001530}
1531
1532static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1533{
1534 struct hci_cp_sniff_mode *cp;
1535 struct hci_conn *conn;
1536
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001537 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001538
1539 if (!status)
1540 return;
1541
1542 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1543 if (!cp)
1544 return;
1545
1546 hci_dev_lock(hdev);
1547
1548 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001549 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001550 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001551
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001552 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001553 hci_sco_setup(conn, status);
1554 }
1555
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001556 hci_dev_unlock(hdev);
1557}
1558
1559static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1560{
1561 struct hci_cp_exit_sniff_mode *cp;
1562 struct hci_conn *conn;
1563
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001564 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001565
1566 if (!status)
1567 return;
1568
1569 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1570 if (!cp)
1571 return;
1572
1573 hci_dev_lock(hdev);
1574
1575 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001576 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001577 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001578
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001579 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001580 hci_sco_setup(conn, status);
1581 }
1582
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001583 hci_dev_unlock(hdev);
1584}
1585
Johan Hedberg88c3df12012-02-09 14:27:38 +02001586static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1587{
1588 struct hci_cp_disconnect *cp;
1589 struct hci_conn *conn;
1590
1591 if (!status)
1592 return;
1593
1594 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1595 if (!cp)
1596 return;
1597
1598 hci_dev_lock(hdev);
1599
1600 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1601 if (conn)
1602 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001603 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001604
1605 hci_dev_unlock(hdev);
1606}
1607
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001608static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1609{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001610 struct hci_cp_create_phy_link *cp;
1611
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001612 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001613
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001614 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1615 if (!cp)
1616 return;
1617
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001618 hci_dev_lock(hdev);
1619
1620 if (status) {
1621 struct hci_conn *hcon;
1622
1623 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1624 if (hcon)
1625 hci_conn_del(hcon);
1626 } else {
1627 amp_write_remote_assoc(hdev, cp->phy_handle);
1628 }
1629
1630 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001631}
1632
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001633static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1634{
1635 struct hci_cp_accept_phy_link *cp;
1636
1637 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1638
1639 if (status)
1640 return;
1641
1642 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1643 if (!cp)
1644 return;
1645
1646 amp_write_remote_assoc(hdev, cp->phy_handle);
1647}
1648
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02001649static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
1650{
1651 struct hci_cp_le_create_conn *cp;
1652 struct hci_conn *conn;
1653
1654 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1655
1656 /* All connection failure handling is taken care of by the
1657 * hci_le_conn_failed function which is triggered by the HCI
1658 * request completion callbacks used for connecting.
1659 */
1660 if (status)
1661 return;
1662
1663 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1664 if (!cp)
1665 return;
1666
1667 hci_dev_lock(hdev);
1668
1669 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1670 if (!conn)
1671 goto unlock;
1672
1673 /* Store the initiator and responder address information which
1674 * is needed for SMP. These values will not change during the
1675 * lifetime of the connection.
1676 */
1677 conn->init_addr_type = cp->own_address_type;
1678 if (cp->own_address_type == ADDR_LE_DEV_RANDOM)
1679 bacpy(&conn->init_addr, &hdev->random_addr);
1680 else
1681 bacpy(&conn->init_addr, &hdev->bdaddr);
1682
1683 conn->resp_addr_type = cp->peer_addr_type;
1684 bacpy(&conn->resp_addr, &cp->peer_addr);
1685
Johan Hedberg9489eca2014-02-28 17:45:46 +02001686 /* We don't want the connection attempt to stick around
1687 * indefinitely since LE doesn't have a page timeout concept
1688 * like BR/EDR. Set a timer for any connection that doesn't use
1689 * the white list for connecting.
1690 */
1691 if (cp->filter_policy == HCI_LE_USE_PEER_ADDR)
1692 queue_delayed_work(conn->hdev->workqueue,
1693 &conn->le_conn_timeout,
1694 HCI_LE_CONN_TIMEOUT);
1695
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02001696unlock:
1697 hci_dev_unlock(hdev);
1698}
1699
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001700static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001701{
1702 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001703 struct discovery_state *discov = &hdev->discovery;
1704 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001705
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001706 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001707
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001708 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001709
1710 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1711 return;
1712
Andre Guedes3e13fa12013-03-27 20:04:56 -03001713 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1714 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1715
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001716 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001717 return;
1718
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001719 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001720
Andre Guedes343f9352012-02-17 20:39:37 -03001721 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001722 goto unlock;
1723
1724 if (list_empty(&discov->resolve)) {
1725 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1726 goto unlock;
1727 }
1728
1729 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1730 if (e && hci_resolve_name(hdev, e) == 0) {
1731 e->name_state = NAME_PENDING;
1732 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1733 } else {
1734 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1735 }
1736
1737unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001738 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001739}
1740
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001741static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001743 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001744 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 int num_rsp = *((__u8 *) skb->data);
1746
1747 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1748
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001749 if (!num_rsp)
1750 return;
1751
Andre Guedes1519cc12012-03-21 00:03:38 -03001752 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1753 return;
1754
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001756
Johan Hedberge17acd42011-03-30 23:57:16 +03001757 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001758 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001759
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 bacpy(&data.bdaddr, &info->bdaddr);
1761 data.pscan_rep_mode = info->pscan_rep_mode;
1762 data.pscan_period_mode = info->pscan_period_mode;
1763 data.pscan_mode = info->pscan_mode;
1764 memcpy(data.dev_class, info->dev_class, 3);
1765 data.clock_offset = info->clock_offset;
1766 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001767 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001768
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001769 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001770 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001771 info->dev_class, 0, !name_known, ssp, NULL,
1772 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001774
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 hci_dev_unlock(hdev);
1776}
1777
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001778static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001780 struct hci_ev_conn_complete *ev = (void *) skb->data;
1781 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001783 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001784
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001786
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001787 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001788 if (!conn) {
1789 if (ev->link_type != SCO_LINK)
1790 goto unlock;
1791
1792 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1793 if (!conn)
1794 goto unlock;
1795
1796 conn->type = SCO_LINK;
1797 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001798
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001799 if (!ev->status) {
1800 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001801
1802 if (conn->type == ACL_LINK) {
1803 conn->state = BT_CONFIG;
1804 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001805
1806 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1807 !hci_find_link_key(hdev, &ev->bdaddr))
1808 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1809 else
1810 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001811 } else
1812 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001813
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001814 hci_conn_add_sysfs(conn);
1815
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001816 if (test_bit(HCI_AUTH, &hdev->flags))
1817 conn->link_mode |= HCI_LM_AUTH;
1818
1819 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1820 conn->link_mode |= HCI_LM_ENCRYPT;
1821
1822 /* Get remote features */
1823 if (conn->type == ACL_LINK) {
1824 struct hci_cp_read_remote_features cp;
1825 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001826 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001827 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001828 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001829
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001830 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001831 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001832 struct hci_cp_change_conn_ptype cp;
1833 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001834 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001835 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1836 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001837 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001838 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001839 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001840 if (conn->type == ACL_LINK)
Marcel Holtmann64c7b772014-02-18 14:22:20 -08001841 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001842 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001843 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001844
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001845 if (conn->type == ACL_LINK)
1846 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001847
Marcel Holtmann769be972008-07-14 20:13:49 +02001848 if (ev->status) {
1849 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001850 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001851 } else if (ev->link_type != ACL_LINK)
1852 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001853
1854unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001856
1857 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858}
1859
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001860static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001862 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001864 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001866 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001867 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001869 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1870 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871
Szymon Janc138d22e2011-02-17 16:44:23 +01001872 if ((mask & HCI_LM_ACCEPT) &&
Marcel Holtmannb9ee0a72013-10-17 17:24:13 -07001873 !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001875 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877
1878 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001879
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001880 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1881 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001882 memcpy(ie->data.dev_class, ev->dev_class, 3);
1883
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001884 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1885 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001887 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1888 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001889 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 hci_dev_unlock(hdev);
1891 return;
1892 }
1893 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001894
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001896
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897 hci_dev_unlock(hdev);
1898
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001899 if (ev->link_type == ACL_LINK ||
1900 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001901 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001902 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001904 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001906 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1907 cp.role = 0x00; /* Become master */
1908 else
1909 cp.role = 0x01; /* Remain slave */
1910
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001911 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1912 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001913 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001914 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001915 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001916
1917 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001918 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001919
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001920 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1921 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1922 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001923 cp.content_format = cpu_to_le16(hdev->voice_setting);
1924 cp.retrans_effort = 0xff;
1925
1926 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001927 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001928 } else {
1929 conn->state = BT_CONNECT2;
1930 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001931 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932 } else {
1933 /* Connection rejected */
1934 struct hci_cp_reject_conn_req cp;
1935
1936 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001937 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001938 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939 }
1940}
1941
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001942static u8 hci_to_mgmt_reason(u8 err)
1943{
1944 switch (err) {
1945 case HCI_ERROR_CONNECTION_TIMEOUT:
1946 return MGMT_DEV_DISCONN_TIMEOUT;
1947 case HCI_ERROR_REMOTE_USER_TERM:
1948 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1949 case HCI_ERROR_REMOTE_POWER_OFF:
1950 return MGMT_DEV_DISCONN_REMOTE;
1951 case HCI_ERROR_LOCAL_HOST_TERM:
1952 return MGMT_DEV_DISCONN_LOCAL_HOST;
1953 default:
1954 return MGMT_DEV_DISCONN_UNKNOWN;
1955 }
1956}
1957
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001958static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001960 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Andre Guedesabf54a52013-11-07 17:36:09 -03001961 u8 reason = hci_to_mgmt_reason(ev->reason);
Andre Guedes9fcb18e2014-02-26 20:21:48 -03001962 struct hci_conn_params *params;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001963 struct hci_conn *conn;
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02001964 bool mgmt_connected;
Andre Guedes38462202013-11-07 17:36:10 -03001965 u8 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001966
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001967 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001968
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969 hci_dev_lock(hdev);
1970
Marcel Holtmann04837f62006-07-03 10:02:33 +02001971 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001972 if (!conn)
1973 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001974
Andre Guedesabf54a52013-11-07 17:36:09 -03001975 if (ev->status) {
1976 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1977 conn->dst_type, ev->status);
1978 goto unlock;
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001979 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001980
Andre Guedes38462202013-11-07 17:36:10 -03001981 conn->state = BT_CLOSED;
1982
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02001983 mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
1984 mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
1985 reason, mgmt_connected);
Andre Guedesabf54a52013-11-07 17:36:09 -03001986
Andre Guedes38462202013-11-07 17:36:10 -03001987 if (conn->type == ACL_LINK && conn->flush_key)
1988 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg22102462013-10-05 12:01:06 +02001989
Andre Guedes9fcb18e2014-02-26 20:21:48 -03001990 params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
1991 if (params) {
1992 switch (params->auto_connect) {
1993 case HCI_AUTO_CONN_LINK_LOSS:
1994 if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
1995 break;
1996 /* Fall through */
1997
1998 case HCI_AUTO_CONN_ALWAYS:
1999 hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type);
2000 break;
2001
2002 default:
2003 break;
2004 }
2005 }
2006
Andre Guedes38462202013-11-07 17:36:10 -03002007 type = conn->type;
Johan Hedberg22102462013-10-05 12:01:06 +02002008
Andre Guedes38462202013-11-07 17:36:10 -03002009 hci_proto_disconn_cfm(conn, ev->reason);
2010 hci_conn_del(conn);
2011
2012 /* Re-enable advertising if necessary, since it might
2013 * have been disabled by the connection. From the
2014 * HCI_LE_Set_Advertise_Enable command description in
2015 * the core specification (v4.0):
2016 * "The Controller shall continue advertising until the Host
2017 * issues an LE_Set_Advertise_Enable command with
2018 * Advertising_Enable set to 0x00 (Advertising is disabled)
2019 * or until a connection is created or until the Advertising
2020 * is timed out due to Directed Advertising."
2021 */
2022 if (type == LE_LINK)
2023 mgmt_reenable_advertising(hdev);
Johan Hedbergf7520542011-01-20 12:34:39 +02002024
2025unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002026 hci_dev_unlock(hdev);
2027}
2028
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002029static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002030{
2031 struct hci_ev_auth_complete *ev = (void *) skb->data;
2032 struct hci_conn *conn;
2033
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002034 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002035
2036 hci_dev_lock(hdev);
2037
2038 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002039 if (!conn)
2040 goto unlock;
2041
2042 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002043 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002044 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002045 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03002046 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002047 conn->link_mode |= HCI_LM_AUTH;
2048 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03002049 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002050 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02002051 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002052 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002053 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002054
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002055 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
2056 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002057
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002058 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002059 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002060 struct hci_cp_set_conn_encrypt cp;
2061 cp.handle = ev->handle;
2062 cp.encrypt = 0x01;
2063 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002064 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002065 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002066 conn->state = BT_CONNECTED;
2067 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002068 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002069 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002070 } else {
2071 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002072
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002073 hci_conn_hold(conn);
2074 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002075 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002076 }
2077
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002078 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002079 if (!ev->status) {
2080 struct hci_cp_set_conn_encrypt cp;
2081 cp.handle = ev->handle;
2082 cp.encrypt = 0x01;
2083 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002084 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002085 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002086 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002087 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002088 }
2089 }
2090
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002091unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002092 hci_dev_unlock(hdev);
2093}
2094
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002095static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002096{
Johan Hedberg127178d2010-11-18 22:22:29 +02002097 struct hci_ev_remote_name *ev = (void *) skb->data;
2098 struct hci_conn *conn;
2099
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002100 BT_DBG("%s", hdev->name);
2101
2102 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02002103
2104 hci_dev_lock(hdev);
2105
2106 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002107
2108 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2109 goto check_auth;
2110
2111 if (ev->status == 0)
2112 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002113 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002114 else
2115 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2116
2117check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002118 if (!conn)
2119 goto unlock;
2120
2121 if (!hci_outgoing_auth_needed(hdev, conn))
2122 goto unlock;
2123
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002124 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002125 struct hci_cp_auth_requested cp;
2126 cp.handle = __cpu_to_le16(conn->handle);
2127 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2128 }
2129
Johan Hedberg79c6c702011-04-28 11:28:55 -07002130unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002131 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002132}
2133
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002134static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002135{
2136 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2137 struct hci_conn *conn;
2138
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002139 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002140
2141 hci_dev_lock(hdev);
2142
2143 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002144 if (!conn)
2145 goto unlock;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002146
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002147 if (!ev->status) {
2148 if (ev->encrypt) {
2149 /* Encryption implies authentication */
2150 conn->link_mode |= HCI_LM_AUTH;
2151 conn->link_mode |= HCI_LM_ENCRYPT;
2152 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002153
Marcel Holtmann914a6ff2014-02-01 11:52:02 -08002154 /* P-256 authentication key implies FIPS */
2155 if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
2156 conn->link_mode |= HCI_LM_FIPS;
2157
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002158 if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
2159 conn->type == LE_LINK)
2160 set_bit(HCI_CONN_AES_CCM, &conn->flags);
2161 } else {
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002162 conn->link_mode &= ~HCI_LM_ENCRYPT;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002163 clear_bit(HCI_CONN_AES_CCM, &conn->flags);
2164 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002165 }
2166
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002167 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2168
2169 if (ev->status && conn->state == BT_CONNECTED) {
2170 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
2171 hci_conn_drop(conn);
2172 goto unlock;
2173 }
2174
2175 if (conn->state == BT_CONFIG) {
2176 if (!ev->status)
2177 conn->state = BT_CONNECTED;
2178
2179 hci_proto_connect_cfm(conn, ev->status);
2180 hci_conn_drop(conn);
2181 } else
2182 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
2183
Gustavo Padovana7d77232012-05-13 03:20:07 -03002184unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002185 hci_dev_unlock(hdev);
2186}
2187
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002188static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2189 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002190{
2191 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2192 struct hci_conn *conn;
2193
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002194 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002195
2196 hci_dev_lock(hdev);
2197
2198 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2199 if (conn) {
2200 if (!ev->status)
2201 conn->link_mode |= HCI_LM_SECURE;
2202
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002203 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002204
2205 hci_key_change_cfm(conn, ev->status);
2206 }
2207
2208 hci_dev_unlock(hdev);
2209}
2210
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002211static void hci_remote_features_evt(struct hci_dev *hdev,
2212 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002213{
2214 struct hci_ev_remote_features *ev = (void *) skb->data;
2215 struct hci_conn *conn;
2216
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002217 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002218
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002219 hci_dev_lock(hdev);
2220
2221 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002222 if (!conn)
2223 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002224
Johan Hedbergccd556f2010-11-10 17:11:51 +02002225 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002226 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002227
2228 if (conn->state != BT_CONFIG)
2229 goto unlock;
2230
2231 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2232 struct hci_cp_read_remote_ext_features cp;
2233 cp.handle = ev->handle;
2234 cp.page = 0x01;
2235 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002236 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002237 goto unlock;
2238 }
2239
Johan Hedberg671267b2012-05-12 16:11:50 -03002240 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002241 struct hci_cp_remote_name_req cp;
2242 memset(&cp, 0, sizeof(cp));
2243 bacpy(&cp.bdaddr, &conn->dst);
2244 cp.pscan_rep_mode = 0x02;
2245 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002246 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2247 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002248 conn->dst_type, 0, NULL, 0,
2249 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002250
Johan Hedberg127178d2010-11-18 22:22:29 +02002251 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002252 conn->state = BT_CONNECTED;
2253 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002254 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002255 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002256
Johan Hedbergccd556f2010-11-10 17:11:51 +02002257unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002258 hci_dev_unlock(hdev);
2259}
2260
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002261static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002262{
2263 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002264 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002265 __u16 opcode;
2266
2267 skb_pull(skb, sizeof(*ev));
2268
2269 opcode = __le16_to_cpu(ev->opcode);
2270
2271 switch (opcode) {
2272 case HCI_OP_INQUIRY_CANCEL:
2273 hci_cc_inquiry_cancel(hdev, skb);
2274 break;
2275
Andre Guedes4d934832012-03-21 00:03:35 -03002276 case HCI_OP_PERIODIC_INQ:
2277 hci_cc_periodic_inq(hdev, skb);
2278 break;
2279
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002280 case HCI_OP_EXIT_PERIODIC_INQ:
2281 hci_cc_exit_periodic_inq(hdev, skb);
2282 break;
2283
2284 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2285 hci_cc_remote_name_req_cancel(hdev, skb);
2286 break;
2287
2288 case HCI_OP_ROLE_DISCOVERY:
2289 hci_cc_role_discovery(hdev, skb);
2290 break;
2291
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002292 case HCI_OP_READ_LINK_POLICY:
2293 hci_cc_read_link_policy(hdev, skb);
2294 break;
2295
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002296 case HCI_OP_WRITE_LINK_POLICY:
2297 hci_cc_write_link_policy(hdev, skb);
2298 break;
2299
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002300 case HCI_OP_READ_DEF_LINK_POLICY:
2301 hci_cc_read_def_link_policy(hdev, skb);
2302 break;
2303
2304 case HCI_OP_WRITE_DEF_LINK_POLICY:
2305 hci_cc_write_def_link_policy(hdev, skb);
2306 break;
2307
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002308 case HCI_OP_RESET:
2309 hci_cc_reset(hdev, skb);
2310 break;
2311
2312 case HCI_OP_WRITE_LOCAL_NAME:
2313 hci_cc_write_local_name(hdev, skb);
2314 break;
2315
2316 case HCI_OP_READ_LOCAL_NAME:
2317 hci_cc_read_local_name(hdev, skb);
2318 break;
2319
2320 case HCI_OP_WRITE_AUTH_ENABLE:
2321 hci_cc_write_auth_enable(hdev, skb);
2322 break;
2323
2324 case HCI_OP_WRITE_ENCRYPT_MODE:
2325 hci_cc_write_encrypt_mode(hdev, skb);
2326 break;
2327
2328 case HCI_OP_WRITE_SCAN_ENABLE:
2329 hci_cc_write_scan_enable(hdev, skb);
2330 break;
2331
2332 case HCI_OP_READ_CLASS_OF_DEV:
2333 hci_cc_read_class_of_dev(hdev, skb);
2334 break;
2335
2336 case HCI_OP_WRITE_CLASS_OF_DEV:
2337 hci_cc_write_class_of_dev(hdev, skb);
2338 break;
2339
2340 case HCI_OP_READ_VOICE_SETTING:
2341 hci_cc_read_voice_setting(hdev, skb);
2342 break;
2343
2344 case HCI_OP_WRITE_VOICE_SETTING:
2345 hci_cc_write_voice_setting(hdev, skb);
2346 break;
2347
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002348 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2349 hci_cc_read_num_supported_iac(hdev, skb);
2350 break;
2351
Marcel Holtmann333140b2008-07-14 20:13:48 +02002352 case HCI_OP_WRITE_SSP_MODE:
2353 hci_cc_write_ssp_mode(hdev, skb);
2354 break;
2355
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08002356 case HCI_OP_WRITE_SC_SUPPORT:
2357 hci_cc_write_sc_support(hdev, skb);
2358 break;
2359
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002360 case HCI_OP_READ_LOCAL_VERSION:
2361 hci_cc_read_local_version(hdev, skb);
2362 break;
2363
2364 case HCI_OP_READ_LOCAL_COMMANDS:
2365 hci_cc_read_local_commands(hdev, skb);
2366 break;
2367
2368 case HCI_OP_READ_LOCAL_FEATURES:
2369 hci_cc_read_local_features(hdev, skb);
2370 break;
2371
Andre Guedes971e3a42011-06-30 19:20:52 -03002372 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2373 hci_cc_read_local_ext_features(hdev, skb);
2374 break;
2375
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002376 case HCI_OP_READ_BUFFER_SIZE:
2377 hci_cc_read_buffer_size(hdev, skb);
2378 break;
2379
2380 case HCI_OP_READ_BD_ADDR:
2381 hci_cc_read_bd_addr(hdev, skb);
2382 break;
2383
Johan Hedbergf332ec62013-03-15 17:07:11 -05002384 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2385 hci_cc_read_page_scan_activity(hdev, skb);
2386 break;
2387
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002388 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2389 hci_cc_write_page_scan_activity(hdev, skb);
2390 break;
2391
Johan Hedbergf332ec62013-03-15 17:07:11 -05002392 case HCI_OP_READ_PAGE_SCAN_TYPE:
2393 hci_cc_read_page_scan_type(hdev, skb);
2394 break;
2395
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002396 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2397 hci_cc_write_page_scan_type(hdev, skb);
2398 break;
2399
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002400 case HCI_OP_READ_DATA_BLOCK_SIZE:
2401 hci_cc_read_data_block_size(hdev, skb);
2402 break;
2403
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002404 case HCI_OP_READ_FLOW_CONTROL_MODE:
2405 hci_cc_read_flow_control_mode(hdev, skb);
2406 break;
2407
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002408 case HCI_OP_READ_LOCAL_AMP_INFO:
2409 hci_cc_read_local_amp_info(hdev, skb);
2410 break;
2411
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002412 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2413 hci_cc_read_local_amp_assoc(hdev, skb);
2414 break;
2415
Johan Hedbergd5859e22011-01-25 01:19:58 +02002416 case HCI_OP_READ_INQ_RSP_TX_POWER:
2417 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2418 break;
2419
Johan Hedberg980e1a52011-01-22 06:10:07 +02002420 case HCI_OP_PIN_CODE_REPLY:
2421 hci_cc_pin_code_reply(hdev, skb);
2422 break;
2423
2424 case HCI_OP_PIN_CODE_NEG_REPLY:
2425 hci_cc_pin_code_neg_reply(hdev, skb);
2426 break;
2427
Szymon Jancc35938b2011-03-22 13:12:21 +01002428 case HCI_OP_READ_LOCAL_OOB_DATA:
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08002429 hci_cc_read_local_oob_data(hdev, skb);
2430 break;
2431
2432 case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
2433 hci_cc_read_local_oob_ext_data(hdev, skb);
Szymon Jancc35938b2011-03-22 13:12:21 +01002434 break;
2435
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002436 case HCI_OP_LE_READ_BUFFER_SIZE:
2437 hci_cc_le_read_buffer_size(hdev, skb);
2438 break;
2439
Johan Hedberg60e77322013-01-22 14:01:59 +02002440 case HCI_OP_LE_READ_LOCAL_FEATURES:
2441 hci_cc_le_read_local_features(hdev, skb);
2442 break;
2443
Johan Hedberg8fa19092012-10-19 20:57:49 +03002444 case HCI_OP_LE_READ_ADV_TX_POWER:
2445 hci_cc_le_read_adv_tx_power(hdev, skb);
2446 break;
2447
Johan Hedberga5c29682011-02-19 12:05:57 -03002448 case HCI_OP_USER_CONFIRM_REPLY:
2449 hci_cc_user_confirm_reply(hdev, skb);
2450 break;
2451
2452 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2453 hci_cc_user_confirm_neg_reply(hdev, skb);
2454 break;
2455
Brian Gix1143d452011-11-23 08:28:34 -08002456 case HCI_OP_USER_PASSKEY_REPLY:
2457 hci_cc_user_passkey_reply(hdev, skb);
2458 break;
2459
2460 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2461 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002462 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002463
Marcel Holtmann7a4cd512014-02-19 19:52:13 -08002464 case HCI_OP_LE_SET_RANDOM_ADDR:
2465 hci_cc_le_set_random_addr(hdev, skb);
2466 break;
2467
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002468 case HCI_OP_LE_SET_ADV_ENABLE:
2469 hci_cc_le_set_adv_enable(hdev, skb);
2470 break;
2471
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002472 case HCI_OP_LE_SET_SCAN_ENABLE:
2473 hci_cc_le_set_scan_enable(hdev, skb);
2474 break;
2475
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002476 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2477 hci_cc_le_read_white_list_size(hdev, skb);
2478 break;
2479
Marcel Holtmann0f36b582014-02-27 20:37:31 -08002480 case HCI_OP_LE_CLEAR_WHITE_LIST:
2481 hci_cc_le_clear_white_list(hdev, skb);
2482 break;
2483
2484 case HCI_OP_LE_ADD_TO_WHITE_LIST:
2485 hci_cc_le_add_to_white_list(hdev, skb);
2486 break;
2487
2488 case HCI_OP_LE_DEL_FROM_WHITE_LIST:
2489 hci_cc_le_del_from_white_list(hdev, skb);
2490 break;
2491
Johan Hedberg9b008c02013-01-22 14:02:01 +02002492 case HCI_OP_LE_READ_SUPPORTED_STATES:
2493 hci_cc_le_read_supported_states(hdev, skb);
2494 break;
2495
Andre Guedesf9b49302011-06-30 19:20:53 -03002496 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2497 hci_cc_write_le_host_supported(hdev, skb);
2498 break;
2499
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02002500 case HCI_OP_LE_SET_ADV_PARAM:
2501 hci_cc_set_adv_param(hdev, skb);
2502 break;
2503
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002504 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2505 hci_cc_write_remote_amp_assoc(hdev, skb);
2506 break;
2507
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002508 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002509 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002510 break;
2511 }
2512
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002513 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002514 del_timer(&hdev->cmd_timer);
2515
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002516 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002517
Szymon Jancdbccd792012-12-11 08:51:19 +01002518 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002519 atomic_set(&hdev->cmd_cnt, 1);
2520 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002521 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002522 }
2523}
2524
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002525static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002526{
2527 struct hci_ev_cmd_status *ev = (void *) skb->data;
2528 __u16 opcode;
2529
2530 skb_pull(skb, sizeof(*ev));
2531
2532 opcode = __le16_to_cpu(ev->opcode);
2533
2534 switch (opcode) {
2535 case HCI_OP_INQUIRY:
2536 hci_cs_inquiry(hdev, ev->status);
2537 break;
2538
2539 case HCI_OP_CREATE_CONN:
2540 hci_cs_create_conn(hdev, ev->status);
2541 break;
2542
2543 case HCI_OP_ADD_SCO:
2544 hci_cs_add_sco(hdev, ev->status);
2545 break;
2546
Marcel Holtmannf8558552008-07-14 20:13:49 +02002547 case HCI_OP_AUTH_REQUESTED:
2548 hci_cs_auth_requested(hdev, ev->status);
2549 break;
2550
2551 case HCI_OP_SET_CONN_ENCRYPT:
2552 hci_cs_set_conn_encrypt(hdev, ev->status);
2553 break;
2554
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002555 case HCI_OP_REMOTE_NAME_REQ:
2556 hci_cs_remote_name_req(hdev, ev->status);
2557 break;
2558
Marcel Holtmann769be972008-07-14 20:13:49 +02002559 case HCI_OP_READ_REMOTE_FEATURES:
2560 hci_cs_read_remote_features(hdev, ev->status);
2561 break;
2562
2563 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2564 hci_cs_read_remote_ext_features(hdev, ev->status);
2565 break;
2566
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002567 case HCI_OP_SETUP_SYNC_CONN:
2568 hci_cs_setup_sync_conn(hdev, ev->status);
2569 break;
2570
2571 case HCI_OP_SNIFF_MODE:
2572 hci_cs_sniff_mode(hdev, ev->status);
2573 break;
2574
2575 case HCI_OP_EXIT_SNIFF_MODE:
2576 hci_cs_exit_sniff_mode(hdev, ev->status);
2577 break;
2578
Johan Hedberg8962ee72011-01-20 12:40:27 +02002579 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002580 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002581 break;
2582
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002583 case HCI_OP_CREATE_PHY_LINK:
2584 hci_cs_create_phylink(hdev, ev->status);
2585 break;
2586
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002587 case HCI_OP_ACCEPT_PHY_LINK:
2588 hci_cs_accept_phylink(hdev, ev->status);
2589 break;
2590
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02002591 case HCI_OP_LE_CREATE_CONN:
2592 hci_cs_le_create_conn(hdev, ev->status);
2593 break;
2594
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002595 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002596 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002597 break;
2598 }
2599
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002600 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002601 del_timer(&hdev->cmd_timer);
2602
Johan Hedberg02350a72013-04-03 21:50:29 +03002603 if (ev->status ||
2604 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2605 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002606
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002607 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002608 atomic_set(&hdev->cmd_cnt, 1);
2609 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002610 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002611 }
2612}
2613
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002614static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002615{
2616 struct hci_ev_role_change *ev = (void *) skb->data;
2617 struct hci_conn *conn;
2618
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002619 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002620
2621 hci_dev_lock(hdev);
2622
2623 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2624 if (conn) {
2625 if (!ev->status) {
2626 if (ev->role)
2627 conn->link_mode &= ~HCI_LM_MASTER;
2628 else
2629 conn->link_mode |= HCI_LM_MASTER;
2630 }
2631
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002632 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002633
2634 hci_role_switch_cfm(conn, ev->status, ev->role);
2635 }
2636
2637 hci_dev_unlock(hdev);
2638}
2639
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002640static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002641{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002642 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002643 int i;
2644
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002645 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2646 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2647 return;
2648 }
2649
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002650 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002651 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002652 BT_DBG("%s bad parameters", hdev->name);
2653 return;
2654 }
2655
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002656 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2657
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002658 for (i = 0; i < ev->num_hndl; i++) {
2659 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002660 struct hci_conn *conn;
2661 __u16 handle, count;
2662
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002663 handle = __le16_to_cpu(info->handle);
2664 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665
2666 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002667 if (!conn)
2668 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002670 conn->sent -= count;
2671
2672 switch (conn->type) {
2673 case ACL_LINK:
2674 hdev->acl_cnt += count;
2675 if (hdev->acl_cnt > hdev->acl_pkts)
2676 hdev->acl_cnt = hdev->acl_pkts;
2677 break;
2678
2679 case LE_LINK:
2680 if (hdev->le_pkts) {
2681 hdev->le_cnt += count;
2682 if (hdev->le_cnt > hdev->le_pkts)
2683 hdev->le_cnt = hdev->le_pkts;
2684 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002685 hdev->acl_cnt += count;
2686 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002687 hdev->acl_cnt = hdev->acl_pkts;
2688 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002689 break;
2690
2691 case SCO_LINK:
2692 hdev->sco_cnt += count;
2693 if (hdev->sco_cnt > hdev->sco_pkts)
2694 hdev->sco_cnt = hdev->sco_pkts;
2695 break;
2696
2697 default:
2698 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2699 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002700 }
2701 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002702
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002703 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704}
2705
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002706static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2707 __u16 handle)
2708{
2709 struct hci_chan *chan;
2710
2711 switch (hdev->dev_type) {
2712 case HCI_BREDR:
2713 return hci_conn_hash_lookup_handle(hdev, handle);
2714 case HCI_AMP:
2715 chan = hci_chan_lookup_handle(hdev, handle);
2716 if (chan)
2717 return chan->conn;
2718 break;
2719 default:
2720 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2721 break;
2722 }
2723
2724 return NULL;
2725}
2726
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002727static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002728{
2729 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2730 int i;
2731
2732 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2733 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2734 return;
2735 }
2736
2737 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002738 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002739 BT_DBG("%s bad parameters", hdev->name);
2740 return;
2741 }
2742
2743 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002744 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002745
2746 for (i = 0; i < ev->num_hndl; i++) {
2747 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002748 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002749 __u16 handle, block_count;
2750
2751 handle = __le16_to_cpu(info->handle);
2752 block_count = __le16_to_cpu(info->blocks);
2753
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002754 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002755 if (!conn)
2756 continue;
2757
2758 conn->sent -= block_count;
2759
2760 switch (conn->type) {
2761 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002762 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002763 hdev->block_cnt += block_count;
2764 if (hdev->block_cnt > hdev->num_blocks)
2765 hdev->block_cnt = hdev->num_blocks;
2766 break;
2767
2768 default:
2769 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2770 break;
2771 }
2772 }
2773
2774 queue_work(hdev->workqueue, &hdev->tx_work);
2775}
2776
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002777static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002778{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002779 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002780 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002781
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002782 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002783
2784 hci_dev_lock(hdev);
2785
Marcel Holtmann04837f62006-07-03 10:02:33 +02002786 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2787 if (conn) {
2788 conn->mode = ev->mode;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002789
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002790 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2791 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002792 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002793 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002794 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002795 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002796 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002797
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002798 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002799 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002800 }
2801
2802 hci_dev_unlock(hdev);
2803}
2804
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002805static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002806{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002807 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2808 struct hci_conn *conn;
2809
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002810 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002811
2812 hci_dev_lock(hdev);
2813
2814 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002815 if (!conn)
2816 goto unlock;
2817
2818 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002819 hci_conn_hold(conn);
2820 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002821 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002822 }
2823
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002824 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002825 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002826 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002827 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002828 u8 secure;
2829
2830 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2831 secure = 1;
2832 else
2833 secure = 0;
2834
Johan Hedberg744cf192011-11-08 20:40:14 +02002835 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002836 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002837
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002838unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002839 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002840}
2841
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002842static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002843{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002844 struct hci_ev_link_key_req *ev = (void *) skb->data;
2845 struct hci_cp_link_key_reply cp;
2846 struct hci_conn *conn;
2847 struct link_key *key;
2848
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002849 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002850
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002851 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002852 return;
2853
2854 hci_dev_lock(hdev);
2855
2856 key = hci_find_link_key(hdev, &ev->bdaddr);
2857 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002858 BT_DBG("%s link key not found for %pMR", hdev->name,
2859 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002860 goto not_found;
2861 }
2862
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002863 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2864 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002865
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002866 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002867 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002868 BT_DBG("%s ignoring debug key", hdev->name);
2869 goto not_found;
2870 }
2871
2872 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002873 if (conn) {
Marcel Holtmann66138ce2014-01-10 02:07:20 -08002874 if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
2875 key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002876 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002877 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2878 goto not_found;
2879 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002880
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002881 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002882 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002883 BT_DBG("%s ignoring key unauthenticated for high security",
2884 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002885 goto not_found;
2886 }
2887
2888 conn->key_type = key->type;
2889 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002890 }
2891
2892 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002893 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002894
2895 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2896
2897 hci_dev_unlock(hdev);
2898
2899 return;
2900
2901not_found:
2902 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2903 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904}
2905
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002906static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002907{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002908 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2909 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002910 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002911
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002912 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002913
2914 hci_dev_lock(hdev);
2915
2916 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2917 if (conn) {
2918 hci_conn_hold(conn);
2919 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002920 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002921
2922 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2923 conn->key_type = ev->key_type;
2924
David Herrmann76a68ba2013-04-06 20:28:37 +02002925 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002926 }
2927
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002928 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002929 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002930 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002931
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002932 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002933}
2934
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002935static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002936{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002937 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002938 struct hci_conn *conn;
2939
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002940 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002941
2942 hci_dev_lock(hdev);
2943
2944 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002945 if (conn && !ev->status) {
2946 struct inquiry_entry *ie;
2947
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002948 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2949 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002950 ie->data.clock_offset = ev->clock_offset;
2951 ie->timestamp = jiffies;
2952 }
2953 }
2954
2955 hci_dev_unlock(hdev);
2956}
2957
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002958static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002959{
2960 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2961 struct hci_conn *conn;
2962
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002963 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002964
2965 hci_dev_lock(hdev);
2966
2967 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2968 if (conn && !ev->status)
2969 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2970
2971 hci_dev_unlock(hdev);
2972}
2973
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002974static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002975{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002976 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002977 struct inquiry_entry *ie;
2978
2979 BT_DBG("%s", hdev->name);
2980
2981 hci_dev_lock(hdev);
2982
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002983 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2984 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002985 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2986 ie->timestamp = jiffies;
2987 }
2988
2989 hci_dev_unlock(hdev);
2990}
2991
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002992static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2993 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002994{
2995 struct inquiry_data data;
2996 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002997 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002998
2999 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3000
3001 if (!num_rsp)
3002 return;
3003
Andre Guedes1519cc12012-03-21 00:03:38 -03003004 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3005 return;
3006
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003007 hci_dev_lock(hdev);
3008
3009 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01003010 struct inquiry_info_with_rssi_and_pscan_mode *info;
3011 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003012
Johan Hedberge17acd42011-03-30 23:57:16 +03003013 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003014 bacpy(&data.bdaddr, &info->bdaddr);
3015 data.pscan_rep_mode = info->pscan_rep_mode;
3016 data.pscan_period_mode = info->pscan_period_mode;
3017 data.pscan_mode = info->pscan_mode;
3018 memcpy(data.dev_class, info->dev_class, 3);
3019 data.clock_offset = info->clock_offset;
3020 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003021 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003022
3023 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003024 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003025 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003026 info->dev_class, info->rssi,
3027 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003028 }
3029 } else {
3030 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
3031
Johan Hedberge17acd42011-03-30 23:57:16 +03003032 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003033 bacpy(&data.bdaddr, &info->bdaddr);
3034 data.pscan_rep_mode = info->pscan_rep_mode;
3035 data.pscan_period_mode = info->pscan_period_mode;
3036 data.pscan_mode = 0x00;
3037 memcpy(data.dev_class, info->dev_class, 3);
3038 data.clock_offset = info->clock_offset;
3039 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003040 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003041 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003042 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003043 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003044 info->dev_class, info->rssi,
3045 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003046 }
3047 }
3048
3049 hci_dev_unlock(hdev);
3050}
3051
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003052static void hci_remote_ext_features_evt(struct hci_dev *hdev,
3053 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003054{
Marcel Holtmann41a96212008-07-14 20:13:48 +02003055 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
3056 struct hci_conn *conn;
3057
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003058 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003059
Marcel Holtmann41a96212008-07-14 20:13:48 +02003060 hci_dev_lock(hdev);
3061
3062 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02003063 if (!conn)
3064 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003065
Johan Hedbergcad718e2013-04-17 15:00:51 +03003066 if (ev->page < HCI_MAX_PAGES)
3067 memcpy(conn->features[ev->page], ev->features, 8);
3068
Johan Hedbergccd556f2010-11-10 17:11:51 +02003069 if (!ev->status && ev->page == 0x01) {
3070 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003071
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003072 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3073 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003074 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02003075
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05303076 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02003077 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05303078 } else {
3079 /* It is mandatory by the Bluetooth specification that
3080 * Extended Inquiry Results are only used when Secure
3081 * Simple Pairing is enabled, but some devices violate
3082 * this.
3083 *
3084 * To make these devices work, the internal SSP
3085 * enabled flag needs to be cleared if the remote host
3086 * features do not indicate SSP support */
3087 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
3088 }
Marcel Holtmanneb9a8f32014-01-15 22:37:38 -08003089
3090 if (ev->features[0] & LMP_HOST_SC)
3091 set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003092 }
3093
Johan Hedbergccd556f2010-11-10 17:11:51 +02003094 if (conn->state != BT_CONFIG)
3095 goto unlock;
3096
Johan Hedberg671267b2012-05-12 16:11:50 -03003097 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02003098 struct hci_cp_remote_name_req cp;
3099 memset(&cp, 0, sizeof(cp));
3100 bacpy(&cp.bdaddr, &conn->dst);
3101 cp.pscan_rep_mode = 0x02;
3102 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02003103 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3104 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003105 conn->dst_type, 0, NULL, 0,
3106 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02003107
Johan Hedberg127178d2010-11-18 22:22:29 +02003108 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02003109 conn->state = BT_CONNECTED;
3110 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003111 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02003112 }
3113
3114unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02003115 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003116}
3117
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003118static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
3119 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003120{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003121 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
3122 struct hci_conn *conn;
3123
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003124 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003125
3126 hci_dev_lock(hdev);
3127
3128 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02003129 if (!conn) {
3130 if (ev->link_type == ESCO_LINK)
3131 goto unlock;
3132
3133 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
3134 if (!conn)
3135 goto unlock;
3136
3137 conn->type = SCO_LINK;
3138 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003139
Marcel Holtmann732547f2009-04-19 19:14:14 +02003140 switch (ev->status) {
3141 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003142 conn->handle = __le16_to_cpu(ev->handle);
3143 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02003144
3145 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02003146 break;
3147
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02003148 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05003149 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003150 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08003151 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003152 case 0x1f: /* Unspecified error */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003153 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02003154 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
3155 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003156 if (hci_setup_sync(conn, conn->link->handle))
3157 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003158 }
3159 /* fall through */
3160
3161 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003162 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003163 break;
3164 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003165
3166 hci_proto_connect_cfm(conn, ev->status);
3167 if (ev->status)
3168 hci_conn_del(conn);
3169
3170unlock:
3171 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003172}
3173
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07003174static inline size_t eir_get_length(u8 *eir, size_t eir_len)
3175{
3176 size_t parsed = 0;
3177
3178 while (parsed < eir_len) {
3179 u8 field_len = eir[0];
3180
3181 if (field_len == 0)
3182 return parsed;
3183
3184 parsed += field_len + 1;
3185 eir += field_len + 1;
3186 }
3187
3188 return eir_len;
3189}
3190
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003191static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3192 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003193{
3194 struct inquiry_data data;
3195 struct extended_inquiry_info *info = (void *) (skb->data + 1);
3196 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303197 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003198
3199 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3200
3201 if (!num_rsp)
3202 return;
3203
Andre Guedes1519cc12012-03-21 00:03:38 -03003204 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3205 return;
3206
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003207 hci_dev_lock(hdev);
3208
Johan Hedberge17acd42011-03-30 23:57:16 +03003209 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003210 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003211
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003212 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003213 data.pscan_rep_mode = info->pscan_rep_mode;
3214 data.pscan_period_mode = info->pscan_period_mode;
3215 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003216 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003217 data.clock_offset = info->clock_offset;
3218 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003219 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003220
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003221 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003222 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003223 sizeof(info->data),
3224 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003225 else
3226 name_known = true;
3227
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003228 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003229 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303230 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003231 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003232 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303233 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003234 }
3235
3236 hci_dev_unlock(hdev);
3237}
3238
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003239static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3240 struct sk_buff *skb)
3241{
3242 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3243 struct hci_conn *conn;
3244
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003245 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003246 __le16_to_cpu(ev->handle));
3247
3248 hci_dev_lock(hdev);
3249
3250 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3251 if (!conn)
3252 goto unlock;
3253
3254 if (!ev->status)
3255 conn->sec_level = conn->pending_sec_level;
3256
3257 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3258
3259 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003260 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003261 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003262 goto unlock;
3263 }
3264
3265 if (conn->state == BT_CONFIG) {
3266 if (!ev->status)
3267 conn->state = BT_CONNECTED;
3268
3269 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003270 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003271 } else {
3272 hci_auth_cfm(conn, ev->status);
3273
3274 hci_conn_hold(conn);
3275 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003276 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003277 }
3278
3279unlock:
3280 hci_dev_unlock(hdev);
3281}
3282
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003283static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003284{
3285 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003286 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3287 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003288 /* If both remote and local IO capabilities allow MITM
3289 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003290 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3291 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3292 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003293 else
Mikel Astizacabae92013-06-28 10:56:28 +02003294 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003295 }
3296
3297 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003298 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3299 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003300 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003301
3302 return conn->auth_type;
3303}
3304
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003305static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003306{
3307 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3308 struct hci_conn *conn;
3309
3310 BT_DBG("%s", hdev->name);
3311
3312 hci_dev_lock(hdev);
3313
3314 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003315 if (!conn)
3316 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003317
Johan Hedberg03b555e2011-01-04 15:40:05 +02003318 hci_conn_hold(conn);
3319
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003320 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003321 goto unlock;
3322
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003323 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003324 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003325 struct hci_cp_io_capability_reply cp;
3326
3327 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303328 /* Change the IO capability from KeyboardDisplay
3329 * to DisplayYesNo as it is not supported by BT spec. */
3330 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003331 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003332 conn->auth_type = hci_get_auth_req(conn);
3333 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003334
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003335 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3336 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003337 cp.oob_data = 0x01;
3338 else
3339 cp.oob_data = 0x00;
3340
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003341 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003342 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003343 } else {
3344 struct hci_cp_io_capability_neg_reply cp;
3345
3346 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003347 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003348
3349 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003350 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003351 }
3352
3353unlock:
3354 hci_dev_unlock(hdev);
3355}
3356
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003357static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003358{
3359 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3360 struct hci_conn *conn;
3361
3362 BT_DBG("%s", hdev->name);
3363
3364 hci_dev_lock(hdev);
3365
3366 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3367 if (!conn)
3368 goto unlock;
3369
Johan Hedberg03b555e2011-01-04 15:40:05 +02003370 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003371 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003372 if (ev->oob_data)
3373 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003374
3375unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003376 hci_dev_unlock(hdev);
3377}
3378
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003379static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3380 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003381{
3382 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003383 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003384 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003385
3386 BT_DBG("%s", hdev->name);
3387
3388 hci_dev_lock(hdev);
3389
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003390 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003391 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003392
Johan Hedberg7a828902011-04-28 11:28:53 -07003393 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3394 if (!conn)
3395 goto unlock;
3396
3397 loc_mitm = (conn->auth_type & 0x01);
3398 rem_mitm = (conn->remote_auth & 0x01);
3399
3400 /* If we require MITM but the remote device can't provide that
3401 * (it has NoInputNoOutput) then reject the confirmation
3402 * request. The only exception is when we're dedicated bonding
3403 * initiators (connect_cfm_cb set) since then we always have the MITM
3404 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003405 if (!conn->connect_cfm_cb && loc_mitm &&
3406 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003407 BT_DBG("Rejecting request: remote device can't provide MITM");
3408 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003409 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003410 goto unlock;
3411 }
3412
3413 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003414 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3415 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003416
3417 /* If we're not the initiators request authorization to
3418 * proceed from user space (mgmt_user_confirm with
3419 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003420 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003421 BT_DBG("Confirming auto-accept as acceptor");
3422 confirm_hint = 1;
3423 goto confirm;
3424 }
3425
Johan Hedberg9f616562011-04-28 11:28:54 -07003426 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003427 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003428
3429 if (hdev->auto_accept_delay > 0) {
3430 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
Johan Hedberg7bc18d92013-10-16 18:11:39 +03003431 queue_delayed_work(conn->hdev->workqueue,
3432 &conn->auto_accept_work, delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003433 goto unlock;
3434 }
3435
Johan Hedberg7a828902011-04-28 11:28:53 -07003436 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003437 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003438 goto unlock;
3439 }
3440
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003441confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003442 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003443 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003444
3445unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003446 hci_dev_unlock(hdev);
3447}
3448
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003449static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3450 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003451{
3452 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3453
3454 BT_DBG("%s", hdev->name);
3455
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003456 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003457 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003458}
3459
Johan Hedberg92a25252012-09-06 18:39:26 +03003460static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3461 struct sk_buff *skb)
3462{
3463 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3464 struct hci_conn *conn;
3465
3466 BT_DBG("%s", hdev->name);
3467
3468 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3469 if (!conn)
3470 return;
3471
3472 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3473 conn->passkey_entered = 0;
3474
3475 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3476 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3477 conn->dst_type, conn->passkey_notify,
3478 conn->passkey_entered);
3479}
3480
3481static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3482{
3483 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3484 struct hci_conn *conn;
3485
3486 BT_DBG("%s", hdev->name);
3487
3488 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3489 if (!conn)
3490 return;
3491
3492 switch (ev->type) {
3493 case HCI_KEYPRESS_STARTED:
3494 conn->passkey_entered = 0;
3495 return;
3496
3497 case HCI_KEYPRESS_ENTERED:
3498 conn->passkey_entered++;
3499 break;
3500
3501 case HCI_KEYPRESS_ERASED:
3502 conn->passkey_entered--;
3503 break;
3504
3505 case HCI_KEYPRESS_CLEARED:
3506 conn->passkey_entered = 0;
3507 break;
3508
3509 case HCI_KEYPRESS_COMPLETED:
3510 return;
3511 }
3512
3513 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3514 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3515 conn->dst_type, conn->passkey_notify,
3516 conn->passkey_entered);
3517}
3518
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003519static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3520 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003521{
3522 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3523 struct hci_conn *conn;
3524
3525 BT_DBG("%s", hdev->name);
3526
3527 hci_dev_lock(hdev);
3528
3529 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003530 if (!conn)
3531 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003532
Johan Hedberg2a611692011-02-19 12:06:00 -03003533 /* To avoid duplicate auth_failed events to user space we check
3534 * the HCI_CONN_AUTH_PEND flag which will be set if we
3535 * initiated the authentication. A traditional auth_complete
3536 * event gets always produced as initiator and is also mapped to
3537 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003538 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003539 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003540 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003541
David Herrmann76a68ba2013-04-06 20:28:37 +02003542 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003543
3544unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003545 hci_dev_unlock(hdev);
3546}
3547
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003548static void hci_remote_host_features_evt(struct hci_dev *hdev,
3549 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003550{
3551 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3552 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003553 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003554
3555 BT_DBG("%s", hdev->name);
3556
3557 hci_dev_lock(hdev);
3558
Johan Hedbergcad718e2013-04-17 15:00:51 +03003559 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3560 if (conn)
3561 memcpy(conn->features[1], ev->features, 8);
3562
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003563 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3564 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003565 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003566
3567 hci_dev_unlock(hdev);
3568}
3569
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003570static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3571 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003572{
3573 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3574 struct oob_data *data;
3575
3576 BT_DBG("%s", hdev->name);
3577
3578 hci_dev_lock(hdev);
3579
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003580 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003581 goto unlock;
3582
Szymon Janc2763eda2011-03-22 13:12:22 +01003583 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3584 if (data) {
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003585 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
3586 struct hci_cp_remote_oob_ext_data_reply cp;
Szymon Janc2763eda2011-03-22 13:12:22 +01003587
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003588 bacpy(&cp.bdaddr, &ev->bdaddr);
3589 memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
3590 memcpy(cp.randomizer192, data->randomizer192,
3591 sizeof(cp.randomizer192));
3592 memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
3593 memcpy(cp.randomizer256, data->randomizer256,
3594 sizeof(cp.randomizer256));
Szymon Janc2763eda2011-03-22 13:12:22 +01003595
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003596 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
3597 sizeof(cp), &cp);
3598 } else {
3599 struct hci_cp_remote_oob_data_reply cp;
3600
3601 bacpy(&cp.bdaddr, &ev->bdaddr);
3602 memcpy(cp.hash, data->hash192, sizeof(cp.hash));
3603 memcpy(cp.randomizer, data->randomizer192,
3604 sizeof(cp.randomizer));
3605
3606 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
3607 sizeof(cp), &cp);
3608 }
Szymon Janc2763eda2011-03-22 13:12:22 +01003609 } else {
3610 struct hci_cp_remote_oob_data_neg_reply cp;
3611
3612 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003613 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
3614 sizeof(cp), &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003615 }
3616
Szymon Jance1ba1f12011-04-06 13:01:59 +02003617unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003618 hci_dev_unlock(hdev);
3619}
3620
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003621static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3622 struct sk_buff *skb)
3623{
3624 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3625 struct hci_conn *hcon, *bredr_hcon;
3626
3627 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3628 ev->status);
3629
3630 hci_dev_lock(hdev);
3631
3632 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3633 if (!hcon) {
3634 hci_dev_unlock(hdev);
3635 return;
3636 }
3637
3638 if (ev->status) {
3639 hci_conn_del(hcon);
3640 hci_dev_unlock(hdev);
3641 return;
3642 }
3643
3644 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3645
3646 hcon->state = BT_CONNECTED;
3647 bacpy(&hcon->dst, &bredr_hcon->dst);
3648
3649 hci_conn_hold(hcon);
3650 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003651 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003652
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003653 hci_conn_add_sysfs(hcon);
3654
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003655 amp_physical_cfm(bredr_hcon, hcon);
3656
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003657 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003658}
3659
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003660static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3661{
3662 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3663 struct hci_conn *hcon;
3664 struct hci_chan *hchan;
3665 struct amp_mgr *mgr;
3666
3667 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3668 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3669 ev->status);
3670
3671 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3672 if (!hcon)
3673 return;
3674
3675 /* Create AMP hchan */
3676 hchan = hci_chan_create(hcon);
3677 if (!hchan)
3678 return;
3679
3680 hchan->handle = le16_to_cpu(ev->handle);
3681
3682 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3683
3684 mgr = hcon->amp_mgr;
3685 if (mgr && mgr->bredr_chan) {
3686 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3687
3688 l2cap_chan_lock(bredr_chan);
3689
3690 bredr_chan->conn->mtu = hdev->block_mtu;
3691 l2cap_logical_cfm(bredr_chan, hchan, 0);
3692 hci_conn_hold(hcon);
3693
3694 l2cap_chan_unlock(bredr_chan);
3695 }
3696}
3697
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003698static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3699 struct sk_buff *skb)
3700{
3701 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3702 struct hci_chan *hchan;
3703
3704 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3705 le16_to_cpu(ev->handle), ev->status);
3706
3707 if (ev->status)
3708 return;
3709
3710 hci_dev_lock(hdev);
3711
3712 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3713 if (!hchan)
3714 goto unlock;
3715
3716 amp_destroy_logical_link(hchan, ev->reason);
3717
3718unlock:
3719 hci_dev_unlock(hdev);
3720}
3721
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003722static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3723 struct sk_buff *skb)
3724{
3725 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3726 struct hci_conn *hcon;
3727
3728 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3729
3730 if (ev->status)
3731 return;
3732
3733 hci_dev_lock(hdev);
3734
3735 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3736 if (hcon) {
3737 hcon->state = BT_CLOSED;
3738 hci_conn_del(hcon);
3739 }
3740
3741 hci_dev_unlock(hdev);
3742}
3743
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003744static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003745{
3746 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3747 struct hci_conn *conn;
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003748 struct smp_irk *irk;
Ville Tervofcd89c02011-02-10 22:38:47 -03003749
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003750 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003751
3752 hci_dev_lock(hdev);
3753
Andre Guedesb47a09b2012-07-27 15:10:15 -03003754 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003755 if (!conn) {
3756 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3757 if (!conn) {
3758 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003759 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003760 }
Andre Guedes29b79882011-05-31 14:20:54 -03003761
3762 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003763
Marcel Holtmann880be4e2013-10-13 07:25:18 -07003764 /* The advertising parameters for own address type
3765 * define which source address and source address
3766 * type this connections has.
3767 */
3768 if (bacmp(&conn->src, BDADDR_ANY)) {
3769 conn->src_type = ADDR_LE_DEV_PUBLIC;
3770 } else {
3771 bacpy(&conn->src, &hdev->static_addr);
3772 conn->src_type = ADDR_LE_DEV_RANDOM;
3773 }
3774
Andre Guedesb9b343d2012-07-27 15:10:11 -03003775 if (ev->role == LE_CONN_ROLE_MASTER) {
3776 conn->out = true;
3777 conn->link_mode |= HCI_LM_MASTER;
3778 }
Johan Hedbergcb1d68f2014-02-28 12:54:16 +02003779
3780 /* If we didn't have a hci_conn object previously
3781 * but we're in master role this must be something
3782 * initiated using a white list. Since white list based
3783 * connections are not "first class citizens" we don't
3784 * have full tracking of them. Therefore, we go ahead
3785 * with a "best effort" approach of determining the
3786 * initiator address based on the HCI_PRIVACY flag.
3787 */
3788 if (conn->out) {
3789 conn->resp_addr_type = ev->bdaddr_type;
3790 bacpy(&conn->resp_addr, &ev->bdaddr);
3791 if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) {
3792 conn->init_addr_type = ADDR_LE_DEV_RANDOM;
3793 bacpy(&conn->init_addr, &hdev->rpa);
3794 } else {
3795 hci_copy_identity_address(hdev,
3796 &conn->init_addr,
3797 &conn->init_addr_type);
3798 }
3799 } else {
3800 /* Set the responder (our side) address type based on
3801 * the advertising address type.
3802 */
3803 conn->resp_addr_type = hdev->adv_addr_type;
3804 if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM)
3805 bacpy(&conn->resp_addr, &hdev->random_addr);
3806 else
3807 bacpy(&conn->resp_addr, &hdev->bdaddr);
3808
3809 conn->init_addr_type = ev->bdaddr_type;
3810 bacpy(&conn->init_addr, &ev->bdaddr);
3811 }
Johan Hedberg9489eca2014-02-28 17:45:46 +02003812 } else {
3813 cancel_delayed_work(&conn->le_conn_timeout);
Ville Tervob62f3282011-02-10 22:38:50 -03003814 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003815
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003816 /* Ensure that the hci_conn contains the identity address type
3817 * regardless of which address the connection was made with.
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003818 */
Johan Hedberga1f4c312014-02-27 14:05:41 +02003819 hci_copy_identity_address(hdev, &conn->src, &conn->src_type);
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003820
Marcel Holtmannedb4b462014-02-18 15:13:43 -08003821 /* Lookup the identity address from the stored connection
3822 * address and address type.
3823 *
3824 * When establishing connections to an identity address, the
3825 * connection procedure will store the resolvable random
3826 * address first. Now if it can be converted back into the
3827 * identity address, start using the identity address from
3828 * now on.
3829 */
3830 irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003831 if (irk) {
3832 bacpy(&conn->dst, &irk->bdaddr);
3833 conn->dst_type = irk->addr_type;
3834 }
3835
Andre Guedescd17dec2012-07-27 15:10:16 -03003836 if (ev->status) {
Andre Guedes06c053f2014-02-26 20:21:41 -03003837 hci_le_conn_failed(conn, ev->status);
Andre Guedescd17dec2012-07-27 15:10:16 -03003838 goto unlock;
3839 }
3840
Johan Hedbergb644ba32012-01-17 21:48:47 +02003841 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Marcel Holtmann01fdb0f2014-02-18 14:22:19 -08003842 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003843 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003844
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003845 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003846 conn->handle = __le16_to_cpu(ev->handle);
3847 conn->state = BT_CONNECTED;
3848
Jukka Rissanen18722c22013-12-11 17:05:37 +02003849 if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
3850 set_bit(HCI_CONN_6LOWPAN, &conn->flags);
3851
Ville Tervofcd89c02011-02-10 22:38:47 -03003852 hci_conn_add_sysfs(conn);
3853
3854 hci_proto_connect_cfm(conn, ev->status);
3855
Andre Guedesa4790db2014-02-26 20:21:47 -03003856 hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type);
3857
Ville Tervofcd89c02011-02-10 22:38:47 -03003858unlock:
3859 hci_dev_unlock(hdev);
3860}
3861
Andre Guedesa4790db2014-02-26 20:21:47 -03003862/* This function requires the caller holds hdev->lock */
3863static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
3864 u8 addr_type)
3865{
3866 struct hci_conn *conn;
Andre Guedes5b906a82014-02-26 20:21:53 -03003867 struct smp_irk *irk;
3868
3869 /* If this is a resolvable address, we should resolve it and then
3870 * update address and address type variables.
3871 */
3872 irk = hci_get_irk(hdev, addr, addr_type);
3873 if (irk) {
3874 addr = &irk->bdaddr;
3875 addr_type = irk->addr_type;
3876 }
Andre Guedesa4790db2014-02-26 20:21:47 -03003877
3878 if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
3879 return;
3880
3881 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
3882 HCI_AT_NO_BONDING);
3883 if (!IS_ERR(conn))
3884 return;
3885
3886 switch (PTR_ERR(conn)) {
3887 case -EBUSY:
3888 /* If hci_connect() returns -EBUSY it means there is already
3889 * an LE connection attempt going on. Since controllers don't
3890 * support more than one connection attempt at the time, we
3891 * don't consider this an error case.
3892 */
3893 break;
3894 default:
3895 BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
3896 }
3897}
3898
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003899static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003900{
Andre Guedese95beb42011-09-26 20:48:35 -03003901 u8 num_reports = skb->data[0];
3902 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003903 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003904
Andre Guedesa4790db2014-02-26 20:21:47 -03003905 hci_dev_lock(hdev);
3906
Andre Guedese95beb42011-09-26 20:48:35 -03003907 while (num_reports--) {
3908 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003909
Andre Guedesa4790db2014-02-26 20:21:47 -03003910 if (ev->evt_type == LE_ADV_IND ||
3911 ev->evt_type == LE_ADV_DIRECT_IND)
3912 check_pending_le_conn(hdev, &ev->bdaddr,
3913 ev->bdaddr_type);
3914
Andre Guedes3c9e9192012-01-10 18:20:50 -03003915 rssi = ev->data[ev->length];
3916 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003917 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003918
Andre Guedese95beb42011-09-26 20:48:35 -03003919 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003920 }
Andre Guedesa4790db2014-02-26 20:21:47 -03003921
3922 hci_dev_unlock(hdev);
Andre Guedes9aa04c92011-05-26 16:23:51 -03003923}
3924
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003925static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003926{
3927 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3928 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003929 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003930 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003931 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003932
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003933 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003934
3935 hci_dev_lock(hdev);
3936
3937 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003938 if (conn == NULL)
3939 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003940
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08003941 ltk = hci_find_ltk(hdev, ev->ediv, ev->rand, conn->out);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003942 if (ltk == NULL)
3943 goto not_found;
3944
3945 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003946 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003947
3948 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03003949 conn->pending_sec_level = BT_SECURITY_HIGH;
3950 else
3951 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003952
Andre Guedes89cbb4d2013-07-31 16:25:29 -03003953 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003954
3955 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3956
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003957 if (ltk->type & HCI_SMP_STK) {
3958 list_del(&ltk->list);
3959 kfree(ltk);
3960 }
3961
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003962 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003963
3964 return;
3965
3966not_found:
3967 neg.handle = ev->handle;
3968 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3969 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003970}
3971
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003972static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003973{
3974 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3975
3976 skb_pull(skb, sizeof(*le_ev));
3977
3978 switch (le_ev->subevent) {
3979 case HCI_EV_LE_CONN_COMPLETE:
3980 hci_le_conn_complete_evt(hdev, skb);
3981 break;
3982
Andre Guedes9aa04c92011-05-26 16:23:51 -03003983 case HCI_EV_LE_ADVERTISING_REPORT:
3984 hci_le_adv_report_evt(hdev, skb);
3985 break;
3986
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003987 case HCI_EV_LE_LTK_REQ:
3988 hci_le_ltk_request_evt(hdev, skb);
3989 break;
3990
Ville Tervofcd89c02011-02-10 22:38:47 -03003991 default:
3992 break;
3993 }
3994}
3995
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003996static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3997{
3998 struct hci_ev_channel_selected *ev = (void *) skb->data;
3999 struct hci_conn *hcon;
4000
4001 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
4002
4003 skb_pull(skb, sizeof(*ev));
4004
4005 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
4006 if (!hcon)
4007 return;
4008
4009 amp_read_loc_assoc_final_data(hdev, hcon);
4010}
4011
Linus Torvalds1da177e2005-04-16 15:20:36 -07004012void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
4013{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004014 struct hci_event_hdr *hdr = (void *) skb->data;
4015 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004016
Johan Hedbergb6ddb632013-04-02 13:34:31 +03004017 hci_dev_lock(hdev);
4018
4019 /* Received events are (currently) only needed when a request is
4020 * ongoing so avoid unnecessary memory allocation.
4021 */
4022 if (hdev->req_status == HCI_REQ_PEND) {
4023 kfree_skb(hdev->recv_evt);
4024 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
4025 }
4026
4027 hci_dev_unlock(hdev);
4028
Linus Torvalds1da177e2005-04-16 15:20:36 -07004029 skb_pull(skb, HCI_EVENT_HDR_SIZE);
4030
Johan Hedberg02350a72013-04-03 21:50:29 +03004031 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02004032 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
4033 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03004034
4035 hci_req_cmd_complete(hdev, opcode, 0);
4036 }
4037
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004038 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004039 case HCI_EV_INQUIRY_COMPLETE:
4040 hci_inquiry_complete_evt(hdev, skb);
4041 break;
4042
4043 case HCI_EV_INQUIRY_RESULT:
4044 hci_inquiry_result_evt(hdev, skb);
4045 break;
4046
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004047 case HCI_EV_CONN_COMPLETE:
4048 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02004049 break;
4050
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051 case HCI_EV_CONN_REQUEST:
4052 hci_conn_request_evt(hdev, skb);
4053 break;
4054
Linus Torvalds1da177e2005-04-16 15:20:36 -07004055 case HCI_EV_DISCONN_COMPLETE:
4056 hci_disconn_complete_evt(hdev, skb);
4057 break;
4058
Linus Torvalds1da177e2005-04-16 15:20:36 -07004059 case HCI_EV_AUTH_COMPLETE:
4060 hci_auth_complete_evt(hdev, skb);
4061 break;
4062
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004063 case HCI_EV_REMOTE_NAME:
4064 hci_remote_name_evt(hdev, skb);
4065 break;
4066
Linus Torvalds1da177e2005-04-16 15:20:36 -07004067 case HCI_EV_ENCRYPT_CHANGE:
4068 hci_encrypt_change_evt(hdev, skb);
4069 break;
4070
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004071 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
4072 hci_change_link_key_complete_evt(hdev, skb);
4073 break;
4074
4075 case HCI_EV_REMOTE_FEATURES:
4076 hci_remote_features_evt(hdev, skb);
4077 break;
4078
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004079 case HCI_EV_CMD_COMPLETE:
4080 hci_cmd_complete_evt(hdev, skb);
4081 break;
4082
4083 case HCI_EV_CMD_STATUS:
4084 hci_cmd_status_evt(hdev, skb);
4085 break;
4086
4087 case HCI_EV_ROLE_CHANGE:
4088 hci_role_change_evt(hdev, skb);
4089 break;
4090
4091 case HCI_EV_NUM_COMP_PKTS:
4092 hci_num_comp_pkts_evt(hdev, skb);
4093 break;
4094
4095 case HCI_EV_MODE_CHANGE:
4096 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004097 break;
4098
4099 case HCI_EV_PIN_CODE_REQ:
4100 hci_pin_code_request_evt(hdev, skb);
4101 break;
4102
4103 case HCI_EV_LINK_KEY_REQ:
4104 hci_link_key_request_evt(hdev, skb);
4105 break;
4106
4107 case HCI_EV_LINK_KEY_NOTIFY:
4108 hci_link_key_notify_evt(hdev, skb);
4109 break;
4110
4111 case HCI_EV_CLOCK_OFFSET:
4112 hci_clock_offset_evt(hdev, skb);
4113 break;
4114
Marcel Holtmanna8746412008-07-14 20:13:46 +02004115 case HCI_EV_PKT_TYPE_CHANGE:
4116 hci_pkt_type_change_evt(hdev, skb);
4117 break;
4118
Marcel Holtmann85a1e932005-08-09 20:28:02 -07004119 case HCI_EV_PSCAN_REP_MODE:
4120 hci_pscan_rep_mode_evt(hdev, skb);
4121 break;
4122
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004123 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
4124 hci_inquiry_result_with_rssi_evt(hdev, skb);
4125 break;
4126
4127 case HCI_EV_REMOTE_EXT_FEATURES:
4128 hci_remote_ext_features_evt(hdev, skb);
4129 break;
4130
4131 case HCI_EV_SYNC_CONN_COMPLETE:
4132 hci_sync_conn_complete_evt(hdev, skb);
4133 break;
4134
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004135 case HCI_EV_EXTENDED_INQUIRY_RESULT:
4136 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004137 break;
4138
Johan Hedberg1c2e0042012-06-08 23:31:13 +08004139 case HCI_EV_KEY_REFRESH_COMPLETE:
4140 hci_key_refresh_complete_evt(hdev, skb);
4141 break;
4142
Marcel Holtmann04936842008-07-14 20:13:48 +02004143 case HCI_EV_IO_CAPA_REQUEST:
4144 hci_io_capa_request_evt(hdev, skb);
4145 break;
4146
Johan Hedberg03b555e2011-01-04 15:40:05 +02004147 case HCI_EV_IO_CAPA_REPLY:
4148 hci_io_capa_reply_evt(hdev, skb);
4149 break;
4150
Johan Hedberga5c29682011-02-19 12:05:57 -03004151 case HCI_EV_USER_CONFIRM_REQUEST:
4152 hci_user_confirm_request_evt(hdev, skb);
4153 break;
4154
Brian Gix1143d452011-11-23 08:28:34 -08004155 case HCI_EV_USER_PASSKEY_REQUEST:
4156 hci_user_passkey_request_evt(hdev, skb);
4157 break;
4158
Johan Hedberg92a25252012-09-06 18:39:26 +03004159 case HCI_EV_USER_PASSKEY_NOTIFY:
4160 hci_user_passkey_notify_evt(hdev, skb);
4161 break;
4162
4163 case HCI_EV_KEYPRESS_NOTIFY:
4164 hci_keypress_notify_evt(hdev, skb);
4165 break;
4166
Marcel Holtmann04936842008-07-14 20:13:48 +02004167 case HCI_EV_SIMPLE_PAIR_COMPLETE:
4168 hci_simple_pair_complete_evt(hdev, skb);
4169 break;
4170
Marcel Holtmann41a96212008-07-14 20:13:48 +02004171 case HCI_EV_REMOTE_HOST_FEATURES:
4172 hci_remote_host_features_evt(hdev, skb);
4173 break;
4174
Ville Tervofcd89c02011-02-10 22:38:47 -03004175 case HCI_EV_LE_META:
4176 hci_le_meta_evt(hdev, skb);
4177 break;
4178
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004179 case HCI_EV_CHANNEL_SELECTED:
4180 hci_chan_selected_evt(hdev, skb);
4181 break;
4182
Szymon Janc2763eda2011-03-22 13:12:22 +01004183 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
4184 hci_remote_oob_data_request_evt(hdev, skb);
4185 break;
4186
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03004187 case HCI_EV_PHY_LINK_COMPLETE:
4188 hci_phy_link_complete_evt(hdev, skb);
4189 break;
4190
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004191 case HCI_EV_LOGICAL_LINK_COMPLETE:
4192 hci_loglink_complete_evt(hdev, skb);
4193 break;
4194
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02004195 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
4196 hci_disconn_loglink_complete_evt(hdev, skb);
4197 break;
4198
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02004199 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
4200 hci_disconn_phylink_complete_evt(hdev, skb);
4201 break;
4202
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02004203 case HCI_EV_NUM_COMP_BLOCKS:
4204 hci_num_comp_blocks_evt(hdev, skb);
4205 break;
4206
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004207 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03004208 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004209 break;
4210 }
4211
4212 kfree_skb(skb);
4213 hdev->stat.evt_rx++;
4214}