blob: 62aea2edc231d18819879e562beab8e9905053bc [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
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100962static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
963{
964 __u8 *sent, status = *((__u8 *) skb->data);
965
966 BT_DBG("%s status 0x%2.2x", hdev->name, status);
967
968 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
969 if (!sent)
970 return;
971
972 hci_dev_lock(hdev);
973
974 if (!status) {
975 if (*sent)
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200976 set_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100977 else
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200978 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100979 }
980
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500981 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100982}
983
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300984static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300985 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300986{
987 struct hci_cp_le_set_scan_enable *cp;
988 __u8 status = *((__u8 *) skb->data);
989
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300990 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300991
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300992 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
993 if (!cp)
994 return;
995
Andre Guedes3fd319b2013-04-30 15:29:36 -0300996 if (status)
997 return;
998
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200999 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -03001000 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -03001001 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001002 break;
1003
Andre Guedes76a388b2013-04-04 20:21:02 -03001004 case LE_SCAN_DISABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -03001005 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001006 break;
1007
1008 default:
1009 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1010 break;
Andre Guedes35815082011-05-26 16:23:53 -03001011 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001012}
1013
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001014static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
1015 struct sk_buff *skb)
1016{
1017 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
1018
1019 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
1020
1021 if (!rp->status)
1022 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001023}
1024
Johan Hedberg9b008c02013-01-22 14:02:01 +02001025static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
1026 struct sk_buff *skb)
1027{
1028 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
1029
1030 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1031
1032 if (!rp->status)
1033 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +02001034}
1035
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001036static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1037 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001038{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001039 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001040 __u8 status = *((__u8 *) skb->data);
1041
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001042 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001043
Johan Hedberg06199cf2012-02-22 16:37:11 +02001044 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001045 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001046 return;
1047
Johan Hedberg8f984df2012-02-28 01:07:22 +02001048 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001049 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001050 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001051 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1052 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001053 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001054 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001055 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001056 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001057
1058 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001059 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001060 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001061 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001062 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001063}
1064
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001065static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1066 struct sk_buff *skb)
1067{
1068 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1069
1070 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1071 hdev->name, rp->status, rp->phy_handle);
1072
1073 if (rp->status)
1074 return;
1075
1076 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1077}
1078
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001079static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001080{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001081 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001082
1083 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001084 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001085 return;
1086 }
1087
Andre Guedes89352e72011-11-04 14:16:53 -03001088 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001089}
1090
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001091static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001093 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001096 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001097
1098 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099 if (!cp)
1100 return;
1101
1102 hci_dev_lock(hdev);
1103
1104 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1105
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001106 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107
1108 if (status) {
1109 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001110 if (status != 0x0c || conn->attempt > 2) {
1111 conn->state = BT_CLOSED;
1112 hci_proto_connect_cfm(conn, status);
1113 hci_conn_del(conn);
1114 } else
1115 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116 }
1117 } else {
1118 if (!conn) {
1119 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1120 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001121 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 conn->link_mode |= HCI_LM_MASTER;
1123 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001124 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125 }
1126 }
1127
1128 hci_dev_unlock(hdev);
1129}
1130
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001131static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001133 struct hci_cp_add_sco *cp;
1134 struct hci_conn *acl, *sco;
1135 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001137 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001138
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001139 if (!status)
1140 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001142 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1143 if (!cp)
1144 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001146 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001148 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001149
1150 hci_dev_lock(hdev);
1151
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001152 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001153 if (acl) {
1154 sco = acl->link;
1155 if (sco) {
1156 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001157
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001158 hci_proto_connect_cfm(sco, status);
1159 hci_conn_del(sco);
1160 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001161 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001162
1163 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164}
1165
Marcel Holtmannf8558552008-07-14 20:13:49 +02001166static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1167{
1168 struct hci_cp_auth_requested *cp;
1169 struct hci_conn *conn;
1170
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001171 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001172
1173 if (!status)
1174 return;
1175
1176 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1177 if (!cp)
1178 return;
1179
1180 hci_dev_lock(hdev);
1181
1182 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1183 if (conn) {
1184 if (conn->state == BT_CONFIG) {
1185 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001186 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001187 }
1188 }
1189
1190 hci_dev_unlock(hdev);
1191}
1192
1193static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1194{
1195 struct hci_cp_set_conn_encrypt *cp;
1196 struct hci_conn *conn;
1197
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001198 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001199
1200 if (!status)
1201 return;
1202
1203 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1204 if (!cp)
1205 return;
1206
1207 hci_dev_lock(hdev);
1208
1209 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1210 if (conn) {
1211 if (conn->state == BT_CONFIG) {
1212 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001213 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001214 }
1215 }
1216
1217 hci_dev_unlock(hdev);
1218}
1219
Johan Hedberg127178d2010-11-18 22:22:29 +02001220static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001221 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001222{
Johan Hedberg392599b2010-11-18 22:22:28 +02001223 if (conn->state != BT_CONFIG || !conn->out)
1224 return 0;
1225
Johan Hedberg765c2a92011-01-19 12:06:52 +05301226 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001227 return 0;
1228
1229 /* Only request authentication for SSP connections or non-SSP
Johan Hedberg264b8b42014-01-08 16:40:39 +02001230 * devices with sec_level MEDIUM or HIGH or if MITM protection
1231 * is requested.
1232 */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001233 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
Johan Hedberg264b8b42014-01-08 16:40:39 +02001234 conn->pending_sec_level != BT_SECURITY_HIGH &&
1235 conn->pending_sec_level != BT_SECURITY_MEDIUM)
Johan Hedberg392599b2010-11-18 22:22:28 +02001236 return 0;
1237
Johan Hedberg392599b2010-11-18 22:22:28 +02001238 return 1;
1239}
1240
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001241static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001242 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001243{
1244 struct hci_cp_remote_name_req cp;
1245
1246 memset(&cp, 0, sizeof(cp));
1247
1248 bacpy(&cp.bdaddr, &e->data.bdaddr);
1249 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1250 cp.pscan_mode = e->data.pscan_mode;
1251 cp.clock_offset = e->data.clock_offset;
1252
1253 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1254}
1255
Johan Hedbergb644ba32012-01-17 21:48:47 +02001256static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001257{
1258 struct discovery_state *discov = &hdev->discovery;
1259 struct inquiry_entry *e;
1260
Johan Hedbergb644ba32012-01-17 21:48:47 +02001261 if (list_empty(&discov->resolve))
1262 return false;
1263
1264 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001265 if (!e)
1266 return false;
1267
Johan Hedbergb644ba32012-01-17 21:48:47 +02001268 if (hci_resolve_name(hdev, e) == 0) {
1269 e->name_state = NAME_PENDING;
1270 return true;
1271 }
1272
1273 return false;
1274}
1275
1276static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001277 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001278{
1279 struct discovery_state *discov = &hdev->discovery;
1280 struct inquiry_entry *e;
1281
1282 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001283 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1284 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001285
1286 if (discov->state == DISCOVERY_STOPPED)
1287 return;
1288
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001289 if (discov->state == DISCOVERY_STOPPING)
1290 goto discov_complete;
1291
1292 if (discov->state != DISCOVERY_RESOLVING)
1293 return;
1294
1295 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001296 /* If the device was not found in a list of found devices names of which
1297 * are pending. there is no need to continue resolving a next name as it
1298 * will be done upon receiving another Remote Name Request Complete
1299 * Event */
1300 if (!e)
1301 return;
1302
1303 list_del(&e->list);
1304 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001305 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001306 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1307 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001308 } else {
1309 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001310 }
1311
Johan Hedbergb644ba32012-01-17 21:48:47 +02001312 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001313 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001314
1315discov_complete:
1316 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1317}
1318
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001319static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1320{
Johan Hedberg127178d2010-11-18 22:22:29 +02001321 struct hci_cp_remote_name_req *cp;
1322 struct hci_conn *conn;
1323
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001324 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001325
1326 /* If successful wait for the name req complete event before
1327 * checking for the need to do authentication */
1328 if (!status)
1329 return;
1330
1331 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1332 if (!cp)
1333 return;
1334
1335 hci_dev_lock(hdev);
1336
1337 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001338
1339 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1340 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1341
Johan Hedberg79c6c702011-04-28 11:28:55 -07001342 if (!conn)
1343 goto unlock;
1344
1345 if (!hci_outgoing_auth_needed(hdev, conn))
1346 goto unlock;
1347
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001348 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001349 struct hci_cp_auth_requested auth_cp;
1350
1351 auth_cp.handle = __cpu_to_le16(conn->handle);
1352 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1353 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001354 }
1355
Johan Hedberg79c6c702011-04-28 11:28:55 -07001356unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001357 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001358}
1359
Marcel Holtmann769be972008-07-14 20:13:49 +02001360static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1361{
1362 struct hci_cp_read_remote_features *cp;
1363 struct hci_conn *conn;
1364
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001365 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001366
1367 if (!status)
1368 return;
1369
1370 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1371 if (!cp)
1372 return;
1373
1374 hci_dev_lock(hdev);
1375
1376 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1377 if (conn) {
1378 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001379 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001380 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001381 }
1382 }
1383
1384 hci_dev_unlock(hdev);
1385}
1386
1387static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1388{
1389 struct hci_cp_read_remote_ext_features *cp;
1390 struct hci_conn *conn;
1391
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001392 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001393
1394 if (!status)
1395 return;
1396
1397 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1398 if (!cp)
1399 return;
1400
1401 hci_dev_lock(hdev);
1402
1403 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1404 if (conn) {
1405 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001406 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001407 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001408 }
1409 }
1410
1411 hci_dev_unlock(hdev);
1412}
1413
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001414static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1415{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001416 struct hci_cp_setup_sync_conn *cp;
1417 struct hci_conn *acl, *sco;
1418 __u16 handle;
1419
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001420 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001421
1422 if (!status)
1423 return;
1424
1425 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1426 if (!cp)
1427 return;
1428
1429 handle = __le16_to_cpu(cp->handle);
1430
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001431 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001432
1433 hci_dev_lock(hdev);
1434
1435 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001436 if (acl) {
1437 sco = acl->link;
1438 if (sco) {
1439 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001440
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001441 hci_proto_connect_cfm(sco, status);
1442 hci_conn_del(sco);
1443 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001444 }
1445
1446 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001447}
1448
1449static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1450{
1451 struct hci_cp_sniff_mode *cp;
1452 struct hci_conn *conn;
1453
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001454 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001455
1456 if (!status)
1457 return;
1458
1459 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1460 if (!cp)
1461 return;
1462
1463 hci_dev_lock(hdev);
1464
1465 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001466 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001467 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001468
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001469 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001470 hci_sco_setup(conn, status);
1471 }
1472
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001473 hci_dev_unlock(hdev);
1474}
1475
1476static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1477{
1478 struct hci_cp_exit_sniff_mode *cp;
1479 struct hci_conn *conn;
1480
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001481 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001482
1483 if (!status)
1484 return;
1485
1486 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1487 if (!cp)
1488 return;
1489
1490 hci_dev_lock(hdev);
1491
1492 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001493 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001494 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001495
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001496 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001497 hci_sco_setup(conn, status);
1498 }
1499
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001500 hci_dev_unlock(hdev);
1501}
1502
Johan Hedberg88c3df12012-02-09 14:27:38 +02001503static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1504{
1505 struct hci_cp_disconnect *cp;
1506 struct hci_conn *conn;
1507
1508 if (!status)
1509 return;
1510
1511 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1512 if (!cp)
1513 return;
1514
1515 hci_dev_lock(hdev);
1516
1517 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1518 if (conn)
1519 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001520 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001521
1522 hci_dev_unlock(hdev);
1523}
1524
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001525static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1526{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001527 struct hci_cp_create_phy_link *cp;
1528
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001529 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001530
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001531 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1532 if (!cp)
1533 return;
1534
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001535 hci_dev_lock(hdev);
1536
1537 if (status) {
1538 struct hci_conn *hcon;
1539
1540 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1541 if (hcon)
1542 hci_conn_del(hcon);
1543 } else {
1544 amp_write_remote_assoc(hdev, cp->phy_handle);
1545 }
1546
1547 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001548}
1549
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001550static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1551{
1552 struct hci_cp_accept_phy_link *cp;
1553
1554 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1555
1556 if (status)
1557 return;
1558
1559 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1560 if (!cp)
1561 return;
1562
1563 amp_write_remote_assoc(hdev, cp->phy_handle);
1564}
1565
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001566static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001567{
1568 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001569 struct discovery_state *discov = &hdev->discovery;
1570 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001571
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001572 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001573
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001574 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001575
1576 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1577 return;
1578
Andre Guedes3e13fa12013-03-27 20:04:56 -03001579 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1580 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1581
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001582 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001583 return;
1584
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001585 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001586
Andre Guedes343f9352012-02-17 20:39:37 -03001587 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001588 goto unlock;
1589
1590 if (list_empty(&discov->resolve)) {
1591 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1592 goto unlock;
1593 }
1594
1595 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1596 if (e && hci_resolve_name(hdev, e) == 0) {
1597 e->name_state = NAME_PENDING;
1598 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1599 } else {
1600 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1601 }
1602
1603unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001604 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001605}
1606
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001607static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001609 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001610 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 int num_rsp = *((__u8 *) skb->data);
1612
1613 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1614
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001615 if (!num_rsp)
1616 return;
1617
Andre Guedes1519cc12012-03-21 00:03:38 -03001618 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1619 return;
1620
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001622
Johan Hedberge17acd42011-03-30 23:57:16 +03001623 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001624 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001625
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626 bacpy(&data.bdaddr, &info->bdaddr);
1627 data.pscan_rep_mode = info->pscan_rep_mode;
1628 data.pscan_period_mode = info->pscan_period_mode;
1629 data.pscan_mode = info->pscan_mode;
1630 memcpy(data.dev_class, info->dev_class, 3);
1631 data.clock_offset = info->clock_offset;
1632 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001633 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001634
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001635 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001636 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001637 info->dev_class, 0, !name_known, ssp, NULL,
1638 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001640
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641 hci_dev_unlock(hdev);
1642}
1643
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001644static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001646 struct hci_ev_conn_complete *ev = (void *) skb->data;
1647 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001649 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001650
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001652
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001653 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001654 if (!conn) {
1655 if (ev->link_type != SCO_LINK)
1656 goto unlock;
1657
1658 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1659 if (!conn)
1660 goto unlock;
1661
1662 conn->type = SCO_LINK;
1663 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001664
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001665 if (!ev->status) {
1666 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001667
1668 if (conn->type == ACL_LINK) {
1669 conn->state = BT_CONFIG;
1670 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001671
1672 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1673 !hci_find_link_key(hdev, &ev->bdaddr))
1674 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1675 else
1676 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001677 } else
1678 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001679
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001680 hci_conn_add_sysfs(conn);
1681
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001682 if (test_bit(HCI_AUTH, &hdev->flags))
1683 conn->link_mode |= HCI_LM_AUTH;
1684
1685 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1686 conn->link_mode |= HCI_LM_ENCRYPT;
1687
1688 /* Get remote features */
1689 if (conn->type == ACL_LINK) {
1690 struct hci_cp_read_remote_features cp;
1691 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001692 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001693 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001694 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001695
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001696 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001697 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001698 struct hci_cp_change_conn_ptype cp;
1699 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001700 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001701 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1702 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001703 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001704 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001705 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001706 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001707 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001708 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001709 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001710
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001711 if (conn->type == ACL_LINK)
1712 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001713
Marcel Holtmann769be972008-07-14 20:13:49 +02001714 if (ev->status) {
1715 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001716 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001717 } else if (ev->link_type != ACL_LINK)
1718 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001719
1720unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001722
1723 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724}
1725
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001726static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001728 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001730 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001732 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001733 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001735 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1736 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737
Szymon Janc138d22e2011-02-17 16:44:23 +01001738 if ((mask & HCI_LM_ACCEPT) &&
Marcel Holtmannb9ee0a72013-10-17 17:24:13 -07001739 !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001741 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743
1744 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001745
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001746 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1747 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001748 memcpy(ie->data.dev_class, ev->dev_class, 3);
1749
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001750 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1751 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001753 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1754 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001755 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 hci_dev_unlock(hdev);
1757 return;
1758 }
1759 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001760
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001762
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763 hci_dev_unlock(hdev);
1764
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001765 if (ev->link_type == ACL_LINK ||
1766 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001767 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001768 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001770 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001772 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1773 cp.role = 0x00; /* Become master */
1774 else
1775 cp.role = 0x01; /* Remain slave */
1776
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001777 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1778 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001779 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001780 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001781 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001782
1783 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001784 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001785
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001786 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1787 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1788 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001789 cp.content_format = cpu_to_le16(hdev->voice_setting);
1790 cp.retrans_effort = 0xff;
1791
1792 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001793 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001794 } else {
1795 conn->state = BT_CONNECT2;
1796 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001797 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 } else {
1799 /* Connection rejected */
1800 struct hci_cp_reject_conn_req cp;
1801
1802 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001803 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001804 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 }
1806}
1807
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001808static u8 hci_to_mgmt_reason(u8 err)
1809{
1810 switch (err) {
1811 case HCI_ERROR_CONNECTION_TIMEOUT:
1812 return MGMT_DEV_DISCONN_TIMEOUT;
1813 case HCI_ERROR_REMOTE_USER_TERM:
1814 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1815 case HCI_ERROR_REMOTE_POWER_OFF:
1816 return MGMT_DEV_DISCONN_REMOTE;
1817 case HCI_ERROR_LOCAL_HOST_TERM:
1818 return MGMT_DEV_DISCONN_LOCAL_HOST;
1819 default:
1820 return MGMT_DEV_DISCONN_UNKNOWN;
1821 }
1822}
1823
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001824static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001826 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Andre Guedesabf54a52013-11-07 17:36:09 -03001827 u8 reason = hci_to_mgmt_reason(ev->reason);
Marcel Holtmann04837f62006-07-03 10:02:33 +02001828 struct hci_conn *conn;
Andre Guedes38462202013-11-07 17:36:10 -03001829 u8 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001831 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 hci_dev_lock(hdev);
1834
Marcel Holtmann04837f62006-07-03 10:02:33 +02001835 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001836 if (!conn)
1837 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001838
Andre Guedesabf54a52013-11-07 17:36:09 -03001839 if (ev->status) {
1840 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1841 conn->dst_type, ev->status);
1842 goto unlock;
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001843 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001844
Andre Guedes38462202013-11-07 17:36:10 -03001845 conn->state = BT_CLOSED;
1846
Andre Guedesabf54a52013-11-07 17:36:09 -03001847 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1848 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
1849 conn->dst_type, reason);
1850
Andre Guedes38462202013-11-07 17:36:10 -03001851 if (conn->type == ACL_LINK && conn->flush_key)
1852 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg22102462013-10-05 12:01:06 +02001853
Andre Guedes38462202013-11-07 17:36:10 -03001854 type = conn->type;
Johan Hedberg22102462013-10-05 12:01:06 +02001855
Andre Guedes38462202013-11-07 17:36:10 -03001856 hci_proto_disconn_cfm(conn, ev->reason);
1857 hci_conn_del(conn);
1858
1859 /* Re-enable advertising if necessary, since it might
1860 * have been disabled by the connection. From the
1861 * HCI_LE_Set_Advertise_Enable command description in
1862 * the core specification (v4.0):
1863 * "The Controller shall continue advertising until the Host
1864 * issues an LE_Set_Advertise_Enable command with
1865 * Advertising_Enable set to 0x00 (Advertising is disabled)
1866 * or until a connection is created or until the Advertising
1867 * is timed out due to Directed Advertising."
1868 */
1869 if (type == LE_LINK)
1870 mgmt_reenable_advertising(hdev);
Johan Hedbergf7520542011-01-20 12:34:39 +02001871
1872unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873 hci_dev_unlock(hdev);
1874}
1875
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001876static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001877{
1878 struct hci_ev_auth_complete *ev = (void *) skb->data;
1879 struct hci_conn *conn;
1880
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001881 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001882
1883 hci_dev_lock(hdev);
1884
1885 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001886 if (!conn)
1887 goto unlock;
1888
1889 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001890 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001891 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001892 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001893 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001894 conn->link_mode |= HCI_LM_AUTH;
1895 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001896 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001897 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001898 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001899 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001900 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001901
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001902 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1903 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001904
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001905 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001906 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001907 struct hci_cp_set_conn_encrypt cp;
1908 cp.handle = ev->handle;
1909 cp.encrypt = 0x01;
1910 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001911 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001912 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001913 conn->state = BT_CONNECTED;
1914 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001915 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001916 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001917 } else {
1918 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001919
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001920 hci_conn_hold(conn);
1921 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001922 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001923 }
1924
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001925 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001926 if (!ev->status) {
1927 struct hci_cp_set_conn_encrypt cp;
1928 cp.handle = ev->handle;
1929 cp.encrypt = 0x01;
1930 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001931 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001932 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001933 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001934 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001935 }
1936 }
1937
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001938unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001939 hci_dev_unlock(hdev);
1940}
1941
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001942static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001943{
Johan Hedberg127178d2010-11-18 22:22:29 +02001944 struct hci_ev_remote_name *ev = (void *) skb->data;
1945 struct hci_conn *conn;
1946
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001947 BT_DBG("%s", hdev->name);
1948
1949 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001950
1951 hci_dev_lock(hdev);
1952
1953 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001954
1955 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1956 goto check_auth;
1957
1958 if (ev->status == 0)
1959 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001960 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001961 else
1962 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1963
1964check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001965 if (!conn)
1966 goto unlock;
1967
1968 if (!hci_outgoing_auth_needed(hdev, conn))
1969 goto unlock;
1970
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001971 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001972 struct hci_cp_auth_requested cp;
1973 cp.handle = __cpu_to_le16(conn->handle);
1974 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1975 }
1976
Johan Hedberg79c6c702011-04-28 11:28:55 -07001977unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001978 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001979}
1980
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001981static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001982{
1983 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1984 struct hci_conn *conn;
1985
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001986 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001987
1988 hci_dev_lock(hdev);
1989
1990 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08001991 if (!conn)
1992 goto unlock;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001993
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08001994 if (!ev->status) {
1995 if (ev->encrypt) {
1996 /* Encryption implies authentication */
1997 conn->link_mode |= HCI_LM_AUTH;
1998 conn->link_mode |= HCI_LM_ENCRYPT;
1999 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannf8558552008-07-14 20:13:49 +02002000 } else
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002001 conn->link_mode &= ~HCI_LM_ENCRYPT;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002002 }
2003
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002004 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2005
2006 if (ev->status && conn->state == BT_CONNECTED) {
2007 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
2008 hci_conn_drop(conn);
2009 goto unlock;
2010 }
2011
2012 if (conn->state == BT_CONFIG) {
2013 if (!ev->status)
2014 conn->state = BT_CONNECTED;
2015
2016 hci_proto_connect_cfm(conn, ev->status);
2017 hci_conn_drop(conn);
2018 } else
2019 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
2020
Gustavo Padovana7d77232012-05-13 03:20:07 -03002021unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002022 hci_dev_unlock(hdev);
2023}
2024
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002025static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2026 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002027{
2028 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2029 struct hci_conn *conn;
2030
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002031 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002032
2033 hci_dev_lock(hdev);
2034
2035 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2036 if (conn) {
2037 if (!ev->status)
2038 conn->link_mode |= HCI_LM_SECURE;
2039
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002040 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002041
2042 hci_key_change_cfm(conn, ev->status);
2043 }
2044
2045 hci_dev_unlock(hdev);
2046}
2047
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002048static void hci_remote_features_evt(struct hci_dev *hdev,
2049 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002050{
2051 struct hci_ev_remote_features *ev = (void *) skb->data;
2052 struct hci_conn *conn;
2053
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002054 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002055
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002056 hci_dev_lock(hdev);
2057
2058 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002059 if (!conn)
2060 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002061
Johan Hedbergccd556f2010-11-10 17:11:51 +02002062 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002063 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002064
2065 if (conn->state != BT_CONFIG)
2066 goto unlock;
2067
2068 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2069 struct hci_cp_read_remote_ext_features cp;
2070 cp.handle = ev->handle;
2071 cp.page = 0x01;
2072 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002073 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002074 goto unlock;
2075 }
2076
Johan Hedberg671267b2012-05-12 16:11:50 -03002077 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002078 struct hci_cp_remote_name_req cp;
2079 memset(&cp, 0, sizeof(cp));
2080 bacpy(&cp.bdaddr, &conn->dst);
2081 cp.pscan_rep_mode = 0x02;
2082 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002083 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2084 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002085 conn->dst_type, 0, NULL, 0,
2086 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002087
Johan Hedberg127178d2010-11-18 22:22:29 +02002088 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002089 conn->state = BT_CONNECTED;
2090 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002091 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002092 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002093
Johan Hedbergccd556f2010-11-10 17:11:51 +02002094unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002095 hci_dev_unlock(hdev);
2096}
2097
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002098static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002099{
2100 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002101 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002102 __u16 opcode;
2103
2104 skb_pull(skb, sizeof(*ev));
2105
2106 opcode = __le16_to_cpu(ev->opcode);
2107
2108 switch (opcode) {
2109 case HCI_OP_INQUIRY_CANCEL:
2110 hci_cc_inquiry_cancel(hdev, skb);
2111 break;
2112
Andre Guedes4d934832012-03-21 00:03:35 -03002113 case HCI_OP_PERIODIC_INQ:
2114 hci_cc_periodic_inq(hdev, skb);
2115 break;
2116
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002117 case HCI_OP_EXIT_PERIODIC_INQ:
2118 hci_cc_exit_periodic_inq(hdev, skb);
2119 break;
2120
2121 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2122 hci_cc_remote_name_req_cancel(hdev, skb);
2123 break;
2124
2125 case HCI_OP_ROLE_DISCOVERY:
2126 hci_cc_role_discovery(hdev, skb);
2127 break;
2128
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002129 case HCI_OP_READ_LINK_POLICY:
2130 hci_cc_read_link_policy(hdev, skb);
2131 break;
2132
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002133 case HCI_OP_WRITE_LINK_POLICY:
2134 hci_cc_write_link_policy(hdev, skb);
2135 break;
2136
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002137 case HCI_OP_READ_DEF_LINK_POLICY:
2138 hci_cc_read_def_link_policy(hdev, skb);
2139 break;
2140
2141 case HCI_OP_WRITE_DEF_LINK_POLICY:
2142 hci_cc_write_def_link_policy(hdev, skb);
2143 break;
2144
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002145 case HCI_OP_RESET:
2146 hci_cc_reset(hdev, skb);
2147 break;
2148
2149 case HCI_OP_WRITE_LOCAL_NAME:
2150 hci_cc_write_local_name(hdev, skb);
2151 break;
2152
2153 case HCI_OP_READ_LOCAL_NAME:
2154 hci_cc_read_local_name(hdev, skb);
2155 break;
2156
2157 case HCI_OP_WRITE_AUTH_ENABLE:
2158 hci_cc_write_auth_enable(hdev, skb);
2159 break;
2160
2161 case HCI_OP_WRITE_ENCRYPT_MODE:
2162 hci_cc_write_encrypt_mode(hdev, skb);
2163 break;
2164
2165 case HCI_OP_WRITE_SCAN_ENABLE:
2166 hci_cc_write_scan_enable(hdev, skb);
2167 break;
2168
2169 case HCI_OP_READ_CLASS_OF_DEV:
2170 hci_cc_read_class_of_dev(hdev, skb);
2171 break;
2172
2173 case HCI_OP_WRITE_CLASS_OF_DEV:
2174 hci_cc_write_class_of_dev(hdev, skb);
2175 break;
2176
2177 case HCI_OP_READ_VOICE_SETTING:
2178 hci_cc_read_voice_setting(hdev, skb);
2179 break;
2180
2181 case HCI_OP_WRITE_VOICE_SETTING:
2182 hci_cc_write_voice_setting(hdev, skb);
2183 break;
2184
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002185 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2186 hci_cc_read_num_supported_iac(hdev, skb);
2187 break;
2188
Marcel Holtmann333140b2008-07-14 20:13:48 +02002189 case HCI_OP_WRITE_SSP_MODE:
2190 hci_cc_write_ssp_mode(hdev, skb);
2191 break;
2192
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08002193 case HCI_OP_WRITE_SC_SUPPORT:
2194 hci_cc_write_sc_support(hdev, skb);
2195 break;
2196
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002197 case HCI_OP_READ_LOCAL_VERSION:
2198 hci_cc_read_local_version(hdev, skb);
2199 break;
2200
2201 case HCI_OP_READ_LOCAL_COMMANDS:
2202 hci_cc_read_local_commands(hdev, skb);
2203 break;
2204
2205 case HCI_OP_READ_LOCAL_FEATURES:
2206 hci_cc_read_local_features(hdev, skb);
2207 break;
2208
Andre Guedes971e3a42011-06-30 19:20:52 -03002209 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2210 hci_cc_read_local_ext_features(hdev, skb);
2211 break;
2212
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002213 case HCI_OP_READ_BUFFER_SIZE:
2214 hci_cc_read_buffer_size(hdev, skb);
2215 break;
2216
2217 case HCI_OP_READ_BD_ADDR:
2218 hci_cc_read_bd_addr(hdev, skb);
2219 break;
2220
Johan Hedbergf332ec62013-03-15 17:07:11 -05002221 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2222 hci_cc_read_page_scan_activity(hdev, skb);
2223 break;
2224
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002225 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2226 hci_cc_write_page_scan_activity(hdev, skb);
2227 break;
2228
Johan Hedbergf332ec62013-03-15 17:07:11 -05002229 case HCI_OP_READ_PAGE_SCAN_TYPE:
2230 hci_cc_read_page_scan_type(hdev, skb);
2231 break;
2232
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002233 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2234 hci_cc_write_page_scan_type(hdev, skb);
2235 break;
2236
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002237 case HCI_OP_READ_DATA_BLOCK_SIZE:
2238 hci_cc_read_data_block_size(hdev, skb);
2239 break;
2240
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002241 case HCI_OP_READ_FLOW_CONTROL_MODE:
2242 hci_cc_read_flow_control_mode(hdev, skb);
2243 break;
2244
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002245 case HCI_OP_READ_LOCAL_AMP_INFO:
2246 hci_cc_read_local_amp_info(hdev, skb);
2247 break;
2248
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002249 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2250 hci_cc_read_local_amp_assoc(hdev, skb);
2251 break;
2252
Johan Hedbergd5859e22011-01-25 01:19:58 +02002253 case HCI_OP_READ_INQ_RSP_TX_POWER:
2254 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2255 break;
2256
Johan Hedberg980e1a52011-01-22 06:10:07 +02002257 case HCI_OP_PIN_CODE_REPLY:
2258 hci_cc_pin_code_reply(hdev, skb);
2259 break;
2260
2261 case HCI_OP_PIN_CODE_NEG_REPLY:
2262 hci_cc_pin_code_neg_reply(hdev, skb);
2263 break;
2264
Szymon Jancc35938b2011-03-22 13:12:21 +01002265 case HCI_OP_READ_LOCAL_OOB_DATA:
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08002266 hci_cc_read_local_oob_data(hdev, skb);
2267 break;
2268
2269 case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
2270 hci_cc_read_local_oob_ext_data(hdev, skb);
Szymon Jancc35938b2011-03-22 13:12:21 +01002271 break;
2272
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002273 case HCI_OP_LE_READ_BUFFER_SIZE:
2274 hci_cc_le_read_buffer_size(hdev, skb);
2275 break;
2276
Johan Hedberg60e77322013-01-22 14:01:59 +02002277 case HCI_OP_LE_READ_LOCAL_FEATURES:
2278 hci_cc_le_read_local_features(hdev, skb);
2279 break;
2280
Johan Hedberg8fa19092012-10-19 20:57:49 +03002281 case HCI_OP_LE_READ_ADV_TX_POWER:
2282 hci_cc_le_read_adv_tx_power(hdev, skb);
2283 break;
2284
Johan Hedberga5c29682011-02-19 12:05:57 -03002285 case HCI_OP_USER_CONFIRM_REPLY:
2286 hci_cc_user_confirm_reply(hdev, skb);
2287 break;
2288
2289 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2290 hci_cc_user_confirm_neg_reply(hdev, skb);
2291 break;
2292
Brian Gix1143d452011-11-23 08:28:34 -08002293 case HCI_OP_USER_PASSKEY_REPLY:
2294 hci_cc_user_passkey_reply(hdev, skb);
2295 break;
2296
2297 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2298 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002299 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002300
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002301 case HCI_OP_LE_SET_ADV_ENABLE:
2302 hci_cc_le_set_adv_enable(hdev, skb);
2303 break;
2304
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002305 case HCI_OP_LE_SET_SCAN_ENABLE:
2306 hci_cc_le_set_scan_enable(hdev, skb);
2307 break;
2308
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002309 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2310 hci_cc_le_read_white_list_size(hdev, skb);
2311 break;
2312
Johan Hedberg9b008c02013-01-22 14:02:01 +02002313 case HCI_OP_LE_READ_SUPPORTED_STATES:
2314 hci_cc_le_read_supported_states(hdev, skb);
2315 break;
2316
Andre Guedesf9b49302011-06-30 19:20:53 -03002317 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2318 hci_cc_write_le_host_supported(hdev, skb);
2319 break;
2320
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002321 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2322 hci_cc_write_remote_amp_assoc(hdev, skb);
2323 break;
2324
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002325 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002326 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002327 break;
2328 }
2329
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002330 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002331 del_timer(&hdev->cmd_timer);
2332
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002333 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002334
Szymon Jancdbccd792012-12-11 08:51:19 +01002335 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002336 atomic_set(&hdev->cmd_cnt, 1);
2337 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002338 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002339 }
2340}
2341
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002342static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002343{
2344 struct hci_ev_cmd_status *ev = (void *) skb->data;
2345 __u16 opcode;
2346
2347 skb_pull(skb, sizeof(*ev));
2348
2349 opcode = __le16_to_cpu(ev->opcode);
2350
2351 switch (opcode) {
2352 case HCI_OP_INQUIRY:
2353 hci_cs_inquiry(hdev, ev->status);
2354 break;
2355
2356 case HCI_OP_CREATE_CONN:
2357 hci_cs_create_conn(hdev, ev->status);
2358 break;
2359
2360 case HCI_OP_ADD_SCO:
2361 hci_cs_add_sco(hdev, ev->status);
2362 break;
2363
Marcel Holtmannf8558552008-07-14 20:13:49 +02002364 case HCI_OP_AUTH_REQUESTED:
2365 hci_cs_auth_requested(hdev, ev->status);
2366 break;
2367
2368 case HCI_OP_SET_CONN_ENCRYPT:
2369 hci_cs_set_conn_encrypt(hdev, ev->status);
2370 break;
2371
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002372 case HCI_OP_REMOTE_NAME_REQ:
2373 hci_cs_remote_name_req(hdev, ev->status);
2374 break;
2375
Marcel Holtmann769be972008-07-14 20:13:49 +02002376 case HCI_OP_READ_REMOTE_FEATURES:
2377 hci_cs_read_remote_features(hdev, ev->status);
2378 break;
2379
2380 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2381 hci_cs_read_remote_ext_features(hdev, ev->status);
2382 break;
2383
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002384 case HCI_OP_SETUP_SYNC_CONN:
2385 hci_cs_setup_sync_conn(hdev, ev->status);
2386 break;
2387
2388 case HCI_OP_SNIFF_MODE:
2389 hci_cs_sniff_mode(hdev, ev->status);
2390 break;
2391
2392 case HCI_OP_EXIT_SNIFF_MODE:
2393 hci_cs_exit_sniff_mode(hdev, ev->status);
2394 break;
2395
Johan Hedberg8962ee72011-01-20 12:40:27 +02002396 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002397 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002398 break;
2399
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002400 case HCI_OP_CREATE_PHY_LINK:
2401 hci_cs_create_phylink(hdev, ev->status);
2402 break;
2403
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002404 case HCI_OP_ACCEPT_PHY_LINK:
2405 hci_cs_accept_phylink(hdev, ev->status);
2406 break;
2407
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002408 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002409 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002410 break;
2411 }
2412
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002413 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002414 del_timer(&hdev->cmd_timer);
2415
Johan Hedberg02350a72013-04-03 21:50:29 +03002416 if (ev->status ||
2417 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2418 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002419
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002420 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002421 atomic_set(&hdev->cmd_cnt, 1);
2422 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002423 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002424 }
2425}
2426
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002427static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002428{
2429 struct hci_ev_role_change *ev = (void *) skb->data;
2430 struct hci_conn *conn;
2431
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002432 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002433
2434 hci_dev_lock(hdev);
2435
2436 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2437 if (conn) {
2438 if (!ev->status) {
2439 if (ev->role)
2440 conn->link_mode &= ~HCI_LM_MASTER;
2441 else
2442 conn->link_mode |= HCI_LM_MASTER;
2443 }
2444
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002445 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002446
2447 hci_role_switch_cfm(conn, ev->status, ev->role);
2448 }
2449
2450 hci_dev_unlock(hdev);
2451}
2452
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002453static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002454{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002455 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002456 int i;
2457
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002458 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2459 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2460 return;
2461 }
2462
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002463 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002464 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002465 BT_DBG("%s bad parameters", hdev->name);
2466 return;
2467 }
2468
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002469 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2470
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002471 for (i = 0; i < ev->num_hndl; i++) {
2472 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002473 struct hci_conn *conn;
2474 __u16 handle, count;
2475
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002476 handle = __le16_to_cpu(info->handle);
2477 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002478
2479 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002480 if (!conn)
2481 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002482
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002483 conn->sent -= count;
2484
2485 switch (conn->type) {
2486 case ACL_LINK:
2487 hdev->acl_cnt += count;
2488 if (hdev->acl_cnt > hdev->acl_pkts)
2489 hdev->acl_cnt = hdev->acl_pkts;
2490 break;
2491
2492 case LE_LINK:
2493 if (hdev->le_pkts) {
2494 hdev->le_cnt += count;
2495 if (hdev->le_cnt > hdev->le_pkts)
2496 hdev->le_cnt = hdev->le_pkts;
2497 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002498 hdev->acl_cnt += count;
2499 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002500 hdev->acl_cnt = hdev->acl_pkts;
2501 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002502 break;
2503
2504 case SCO_LINK:
2505 hdev->sco_cnt += count;
2506 if (hdev->sco_cnt > hdev->sco_pkts)
2507 hdev->sco_cnt = hdev->sco_pkts;
2508 break;
2509
2510 default:
2511 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2512 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002513 }
2514 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002515
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002516 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002517}
2518
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002519static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2520 __u16 handle)
2521{
2522 struct hci_chan *chan;
2523
2524 switch (hdev->dev_type) {
2525 case HCI_BREDR:
2526 return hci_conn_hash_lookup_handle(hdev, handle);
2527 case HCI_AMP:
2528 chan = hci_chan_lookup_handle(hdev, handle);
2529 if (chan)
2530 return chan->conn;
2531 break;
2532 default:
2533 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2534 break;
2535 }
2536
2537 return NULL;
2538}
2539
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002540static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002541{
2542 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2543 int i;
2544
2545 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2546 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2547 return;
2548 }
2549
2550 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002551 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002552 BT_DBG("%s bad parameters", hdev->name);
2553 return;
2554 }
2555
2556 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002557 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002558
2559 for (i = 0; i < ev->num_hndl; i++) {
2560 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002561 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002562 __u16 handle, block_count;
2563
2564 handle = __le16_to_cpu(info->handle);
2565 block_count = __le16_to_cpu(info->blocks);
2566
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002567 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002568 if (!conn)
2569 continue;
2570
2571 conn->sent -= block_count;
2572
2573 switch (conn->type) {
2574 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002575 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002576 hdev->block_cnt += block_count;
2577 if (hdev->block_cnt > hdev->num_blocks)
2578 hdev->block_cnt = hdev->num_blocks;
2579 break;
2580
2581 default:
2582 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2583 break;
2584 }
2585 }
2586
2587 queue_work(hdev->workqueue, &hdev->tx_work);
2588}
2589
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002590static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002591{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002592 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002593 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002594
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002595 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002596
2597 hci_dev_lock(hdev);
2598
Marcel Holtmann04837f62006-07-03 10:02:33 +02002599 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2600 if (conn) {
2601 conn->mode = ev->mode;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002602
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002603 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2604 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002605 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002606 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002607 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002608 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002609 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002610
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002611 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002612 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002613 }
2614
2615 hci_dev_unlock(hdev);
2616}
2617
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002618static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002620 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2621 struct hci_conn *conn;
2622
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002623 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002624
2625 hci_dev_lock(hdev);
2626
2627 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002628 if (!conn)
2629 goto unlock;
2630
2631 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002632 hci_conn_hold(conn);
2633 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002634 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002635 }
2636
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002637 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002638 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002639 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002640 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002641 u8 secure;
2642
2643 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2644 secure = 1;
2645 else
2646 secure = 0;
2647
Johan Hedberg744cf192011-11-08 20:40:14 +02002648 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002649 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002650
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002651unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002652 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002653}
2654
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002655static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002656{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002657 struct hci_ev_link_key_req *ev = (void *) skb->data;
2658 struct hci_cp_link_key_reply cp;
2659 struct hci_conn *conn;
2660 struct link_key *key;
2661
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002662 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002663
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002664 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002665 return;
2666
2667 hci_dev_lock(hdev);
2668
2669 key = hci_find_link_key(hdev, &ev->bdaddr);
2670 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002671 BT_DBG("%s link key not found for %pMR", hdev->name,
2672 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002673 goto not_found;
2674 }
2675
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002676 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2677 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002678
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002679 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002680 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002681 BT_DBG("%s ignoring debug key", hdev->name);
2682 goto not_found;
2683 }
2684
2685 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002686 if (conn) {
Marcel Holtmann66138ce2014-01-10 02:07:20 -08002687 if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
2688 key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002689 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002690 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2691 goto not_found;
2692 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002693
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002694 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002695 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002696 BT_DBG("%s ignoring key unauthenticated for high security",
2697 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002698 goto not_found;
2699 }
2700
2701 conn->key_type = key->type;
2702 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002703 }
2704
2705 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002706 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002707
2708 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2709
2710 hci_dev_unlock(hdev);
2711
2712 return;
2713
2714not_found:
2715 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2716 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002717}
2718
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002719static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002720{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002721 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2722 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002723 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002724
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002725 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002726
2727 hci_dev_lock(hdev);
2728
2729 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2730 if (conn) {
2731 hci_conn_hold(conn);
2732 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002733 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002734
2735 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2736 conn->key_type = ev->key_type;
2737
David Herrmann76a68ba2013-04-06 20:28:37 +02002738 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002739 }
2740
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002741 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002742 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002743 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002744
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002745 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002746}
2747
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002748static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002749{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002750 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002751 struct hci_conn *conn;
2752
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002753 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002754
2755 hci_dev_lock(hdev);
2756
2757 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002758 if (conn && !ev->status) {
2759 struct inquiry_entry *ie;
2760
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002761 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2762 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002763 ie->data.clock_offset = ev->clock_offset;
2764 ie->timestamp = jiffies;
2765 }
2766 }
2767
2768 hci_dev_unlock(hdev);
2769}
2770
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002771static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002772{
2773 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2774 struct hci_conn *conn;
2775
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002776 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002777
2778 hci_dev_lock(hdev);
2779
2780 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2781 if (conn && !ev->status)
2782 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2783
2784 hci_dev_unlock(hdev);
2785}
2786
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002787static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002788{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002789 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002790 struct inquiry_entry *ie;
2791
2792 BT_DBG("%s", hdev->name);
2793
2794 hci_dev_lock(hdev);
2795
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002796 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2797 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002798 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2799 ie->timestamp = jiffies;
2800 }
2801
2802 hci_dev_unlock(hdev);
2803}
2804
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002805static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2806 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002807{
2808 struct inquiry_data data;
2809 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002810 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002811
2812 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2813
2814 if (!num_rsp)
2815 return;
2816
Andre Guedes1519cc12012-03-21 00:03:38 -03002817 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2818 return;
2819
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002820 hci_dev_lock(hdev);
2821
2822 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002823 struct inquiry_info_with_rssi_and_pscan_mode *info;
2824 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002825
Johan Hedberge17acd42011-03-30 23:57:16 +03002826 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002827 bacpy(&data.bdaddr, &info->bdaddr);
2828 data.pscan_rep_mode = info->pscan_rep_mode;
2829 data.pscan_period_mode = info->pscan_period_mode;
2830 data.pscan_mode = info->pscan_mode;
2831 memcpy(data.dev_class, info->dev_class, 3);
2832 data.clock_offset = info->clock_offset;
2833 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002834 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002835
2836 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002837 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002838 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002839 info->dev_class, info->rssi,
2840 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002841 }
2842 } else {
2843 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2844
Johan Hedberge17acd42011-03-30 23:57:16 +03002845 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002846 bacpy(&data.bdaddr, &info->bdaddr);
2847 data.pscan_rep_mode = info->pscan_rep_mode;
2848 data.pscan_period_mode = info->pscan_period_mode;
2849 data.pscan_mode = 0x00;
2850 memcpy(data.dev_class, info->dev_class, 3);
2851 data.clock_offset = info->clock_offset;
2852 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002853 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002854 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002855 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002856 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002857 info->dev_class, info->rssi,
2858 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002859 }
2860 }
2861
2862 hci_dev_unlock(hdev);
2863}
2864
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002865static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2866 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002867{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002868 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2869 struct hci_conn *conn;
2870
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002871 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002872
Marcel Holtmann41a96212008-07-14 20:13:48 +02002873 hci_dev_lock(hdev);
2874
2875 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002876 if (!conn)
2877 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002878
Johan Hedbergcad718e2013-04-17 15:00:51 +03002879 if (ev->page < HCI_MAX_PAGES)
2880 memcpy(conn->features[ev->page], ev->features, 8);
2881
Johan Hedbergccd556f2010-11-10 17:11:51 +02002882 if (!ev->status && ev->page == 0x01) {
2883 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002884
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002885 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2886 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002887 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002888
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302889 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002890 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302891 } else {
2892 /* It is mandatory by the Bluetooth specification that
2893 * Extended Inquiry Results are only used when Secure
2894 * Simple Pairing is enabled, but some devices violate
2895 * this.
2896 *
2897 * To make these devices work, the internal SSP
2898 * enabled flag needs to be cleared if the remote host
2899 * features do not indicate SSP support */
2900 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2901 }
Marcel Holtmanneb9a8f32014-01-15 22:37:38 -08002902
2903 if (ev->features[0] & LMP_HOST_SC)
2904 set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002905 }
2906
Johan Hedbergccd556f2010-11-10 17:11:51 +02002907 if (conn->state != BT_CONFIG)
2908 goto unlock;
2909
Johan Hedberg671267b2012-05-12 16:11:50 -03002910 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002911 struct hci_cp_remote_name_req cp;
2912 memset(&cp, 0, sizeof(cp));
2913 bacpy(&cp.bdaddr, &conn->dst);
2914 cp.pscan_rep_mode = 0x02;
2915 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002916 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2917 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002918 conn->dst_type, 0, NULL, 0,
2919 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002920
Johan Hedberg127178d2010-11-18 22:22:29 +02002921 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002922 conn->state = BT_CONNECTED;
2923 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002924 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002925 }
2926
2927unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002928 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002929}
2930
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002931static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2932 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002933{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002934 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2935 struct hci_conn *conn;
2936
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002937 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002938
2939 hci_dev_lock(hdev);
2940
2941 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002942 if (!conn) {
2943 if (ev->link_type == ESCO_LINK)
2944 goto unlock;
2945
2946 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2947 if (!conn)
2948 goto unlock;
2949
2950 conn->type = SCO_LINK;
2951 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002952
Marcel Holtmann732547f2009-04-19 19:14:14 +02002953 switch (ev->status) {
2954 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002955 conn->handle = __le16_to_cpu(ev->handle);
2956 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002957
2958 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002959 break;
2960
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02002961 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05002962 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002963 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002964 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002965 case 0x1f: /* Unspecified error */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002966 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02002967 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2968 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002969 if (hci_setup_sync(conn, conn->link->handle))
2970 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002971 }
2972 /* fall through */
2973
2974 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002975 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002976 break;
2977 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002978
2979 hci_proto_connect_cfm(conn, ev->status);
2980 if (ev->status)
2981 hci_conn_del(conn);
2982
2983unlock:
2984 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002985}
2986
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07002987static inline size_t eir_get_length(u8 *eir, size_t eir_len)
2988{
2989 size_t parsed = 0;
2990
2991 while (parsed < eir_len) {
2992 u8 field_len = eir[0];
2993
2994 if (field_len == 0)
2995 return parsed;
2996
2997 parsed += field_len + 1;
2998 eir += field_len + 1;
2999 }
3000
3001 return eir_len;
3002}
3003
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003004static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3005 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003006{
3007 struct inquiry_data data;
3008 struct extended_inquiry_info *info = (void *) (skb->data + 1);
3009 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303010 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003011
3012 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3013
3014 if (!num_rsp)
3015 return;
3016
Andre Guedes1519cc12012-03-21 00:03:38 -03003017 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3018 return;
3019
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003020 hci_dev_lock(hdev);
3021
Johan Hedberge17acd42011-03-30 23:57:16 +03003022 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003023 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003024
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003025 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003026 data.pscan_rep_mode = info->pscan_rep_mode;
3027 data.pscan_period_mode = info->pscan_period_mode;
3028 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003029 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003030 data.clock_offset = info->clock_offset;
3031 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003032 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003033
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003034 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003035 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003036 sizeof(info->data),
3037 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003038 else
3039 name_known = true;
3040
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003041 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003042 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303043 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003044 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003045 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303046 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003047 }
3048
3049 hci_dev_unlock(hdev);
3050}
3051
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003052static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3053 struct sk_buff *skb)
3054{
3055 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3056 struct hci_conn *conn;
3057
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003058 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003059 __le16_to_cpu(ev->handle));
3060
3061 hci_dev_lock(hdev);
3062
3063 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3064 if (!conn)
3065 goto unlock;
3066
3067 if (!ev->status)
3068 conn->sec_level = conn->pending_sec_level;
3069
3070 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3071
3072 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003073 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003074 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003075 goto unlock;
3076 }
3077
3078 if (conn->state == BT_CONFIG) {
3079 if (!ev->status)
3080 conn->state = BT_CONNECTED;
3081
3082 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003083 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003084 } else {
3085 hci_auth_cfm(conn, ev->status);
3086
3087 hci_conn_hold(conn);
3088 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003089 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003090 }
3091
3092unlock:
3093 hci_dev_unlock(hdev);
3094}
3095
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003096static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003097{
3098 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003099 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3100 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003101 /* If both remote and local IO capabilities allow MITM
3102 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003103 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3104 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3105 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003106 else
Mikel Astizacabae92013-06-28 10:56:28 +02003107 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003108 }
3109
3110 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003111 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3112 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003113 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003114
3115 return conn->auth_type;
3116}
3117
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003118static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003119{
3120 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3121 struct hci_conn *conn;
3122
3123 BT_DBG("%s", hdev->name);
3124
3125 hci_dev_lock(hdev);
3126
3127 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003128 if (!conn)
3129 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003130
Johan Hedberg03b555e2011-01-04 15:40:05 +02003131 hci_conn_hold(conn);
3132
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003133 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003134 goto unlock;
3135
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003136 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003137 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003138 struct hci_cp_io_capability_reply cp;
3139
3140 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303141 /* Change the IO capability from KeyboardDisplay
3142 * to DisplayYesNo as it is not supported by BT spec. */
3143 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003144 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003145 conn->auth_type = hci_get_auth_req(conn);
3146 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003147
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003148 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3149 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003150 cp.oob_data = 0x01;
3151 else
3152 cp.oob_data = 0x00;
3153
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003154 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003155 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003156 } else {
3157 struct hci_cp_io_capability_neg_reply cp;
3158
3159 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003160 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003161
3162 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003163 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003164 }
3165
3166unlock:
3167 hci_dev_unlock(hdev);
3168}
3169
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003170static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003171{
3172 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3173 struct hci_conn *conn;
3174
3175 BT_DBG("%s", hdev->name);
3176
3177 hci_dev_lock(hdev);
3178
3179 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3180 if (!conn)
3181 goto unlock;
3182
Johan Hedberg03b555e2011-01-04 15:40:05 +02003183 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003184 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003185 if (ev->oob_data)
3186 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003187
3188unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003189 hci_dev_unlock(hdev);
3190}
3191
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003192static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3193 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003194{
3195 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003196 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003197 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003198
3199 BT_DBG("%s", hdev->name);
3200
3201 hci_dev_lock(hdev);
3202
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003203 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003204 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003205
Johan Hedberg7a828902011-04-28 11:28:53 -07003206 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3207 if (!conn)
3208 goto unlock;
3209
3210 loc_mitm = (conn->auth_type & 0x01);
3211 rem_mitm = (conn->remote_auth & 0x01);
3212
3213 /* If we require MITM but the remote device can't provide that
3214 * (it has NoInputNoOutput) then reject the confirmation
3215 * request. The only exception is when we're dedicated bonding
3216 * initiators (connect_cfm_cb set) since then we always have the MITM
3217 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003218 if (!conn->connect_cfm_cb && loc_mitm &&
3219 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003220 BT_DBG("Rejecting request: remote device can't provide MITM");
3221 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003222 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003223 goto unlock;
3224 }
3225
3226 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003227 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3228 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003229
3230 /* If we're not the initiators request authorization to
3231 * proceed from user space (mgmt_user_confirm with
3232 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003233 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003234 BT_DBG("Confirming auto-accept as acceptor");
3235 confirm_hint = 1;
3236 goto confirm;
3237 }
3238
Johan Hedberg9f616562011-04-28 11:28:54 -07003239 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003240 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003241
3242 if (hdev->auto_accept_delay > 0) {
3243 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
Johan Hedberg7bc18d92013-10-16 18:11:39 +03003244 queue_delayed_work(conn->hdev->workqueue,
3245 &conn->auto_accept_work, delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003246 goto unlock;
3247 }
3248
Johan Hedberg7a828902011-04-28 11:28:53 -07003249 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003250 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003251 goto unlock;
3252 }
3253
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003254confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003255 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003256 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003257
3258unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003259 hci_dev_unlock(hdev);
3260}
3261
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003262static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3263 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003264{
3265 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3266
3267 BT_DBG("%s", hdev->name);
3268
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003269 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003270 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003271}
3272
Johan Hedberg92a25252012-09-06 18:39:26 +03003273static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3274 struct sk_buff *skb)
3275{
3276 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3277 struct hci_conn *conn;
3278
3279 BT_DBG("%s", hdev->name);
3280
3281 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3282 if (!conn)
3283 return;
3284
3285 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3286 conn->passkey_entered = 0;
3287
3288 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3289 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3290 conn->dst_type, conn->passkey_notify,
3291 conn->passkey_entered);
3292}
3293
3294static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3295{
3296 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3297 struct hci_conn *conn;
3298
3299 BT_DBG("%s", hdev->name);
3300
3301 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3302 if (!conn)
3303 return;
3304
3305 switch (ev->type) {
3306 case HCI_KEYPRESS_STARTED:
3307 conn->passkey_entered = 0;
3308 return;
3309
3310 case HCI_KEYPRESS_ENTERED:
3311 conn->passkey_entered++;
3312 break;
3313
3314 case HCI_KEYPRESS_ERASED:
3315 conn->passkey_entered--;
3316 break;
3317
3318 case HCI_KEYPRESS_CLEARED:
3319 conn->passkey_entered = 0;
3320 break;
3321
3322 case HCI_KEYPRESS_COMPLETED:
3323 return;
3324 }
3325
3326 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3327 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3328 conn->dst_type, conn->passkey_notify,
3329 conn->passkey_entered);
3330}
3331
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003332static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3333 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003334{
3335 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3336 struct hci_conn *conn;
3337
3338 BT_DBG("%s", hdev->name);
3339
3340 hci_dev_lock(hdev);
3341
3342 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003343 if (!conn)
3344 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003345
Johan Hedberg2a611692011-02-19 12:06:00 -03003346 /* To avoid duplicate auth_failed events to user space we check
3347 * the HCI_CONN_AUTH_PEND flag which will be set if we
3348 * initiated the authentication. A traditional auth_complete
3349 * event gets always produced as initiator and is also mapped to
3350 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003351 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003352 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003353 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003354
David Herrmann76a68ba2013-04-06 20:28:37 +02003355 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003356
3357unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003358 hci_dev_unlock(hdev);
3359}
3360
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003361static void hci_remote_host_features_evt(struct hci_dev *hdev,
3362 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003363{
3364 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3365 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003366 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003367
3368 BT_DBG("%s", hdev->name);
3369
3370 hci_dev_lock(hdev);
3371
Johan Hedbergcad718e2013-04-17 15:00:51 +03003372 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3373 if (conn)
3374 memcpy(conn->features[1], ev->features, 8);
3375
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003376 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3377 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003378 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003379
3380 hci_dev_unlock(hdev);
3381}
3382
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003383static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3384 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003385{
3386 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3387 struct oob_data *data;
3388
3389 BT_DBG("%s", hdev->name);
3390
3391 hci_dev_lock(hdev);
3392
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003393 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003394 goto unlock;
3395
Szymon Janc2763eda2011-03-22 13:12:22 +01003396 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3397 if (data) {
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003398 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
3399 struct hci_cp_remote_oob_ext_data_reply cp;
Szymon Janc2763eda2011-03-22 13:12:22 +01003400
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003401 bacpy(&cp.bdaddr, &ev->bdaddr);
3402 memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
3403 memcpy(cp.randomizer192, data->randomizer192,
3404 sizeof(cp.randomizer192));
3405 memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
3406 memcpy(cp.randomizer256, data->randomizer256,
3407 sizeof(cp.randomizer256));
Szymon Janc2763eda2011-03-22 13:12:22 +01003408
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003409 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
3410 sizeof(cp), &cp);
3411 } else {
3412 struct hci_cp_remote_oob_data_reply cp;
3413
3414 bacpy(&cp.bdaddr, &ev->bdaddr);
3415 memcpy(cp.hash, data->hash192, sizeof(cp.hash));
3416 memcpy(cp.randomizer, data->randomizer192,
3417 sizeof(cp.randomizer));
3418
3419 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
3420 sizeof(cp), &cp);
3421 }
Szymon Janc2763eda2011-03-22 13:12:22 +01003422 } else {
3423 struct hci_cp_remote_oob_data_neg_reply cp;
3424
3425 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003426 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
3427 sizeof(cp), &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003428 }
3429
Szymon Jance1ba1f12011-04-06 13:01:59 +02003430unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003431 hci_dev_unlock(hdev);
3432}
3433
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003434static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3435 struct sk_buff *skb)
3436{
3437 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3438 struct hci_conn *hcon, *bredr_hcon;
3439
3440 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3441 ev->status);
3442
3443 hci_dev_lock(hdev);
3444
3445 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3446 if (!hcon) {
3447 hci_dev_unlock(hdev);
3448 return;
3449 }
3450
3451 if (ev->status) {
3452 hci_conn_del(hcon);
3453 hci_dev_unlock(hdev);
3454 return;
3455 }
3456
3457 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3458
3459 hcon->state = BT_CONNECTED;
3460 bacpy(&hcon->dst, &bredr_hcon->dst);
3461
3462 hci_conn_hold(hcon);
3463 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003464 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003465
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003466 hci_conn_add_sysfs(hcon);
3467
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003468 amp_physical_cfm(bredr_hcon, hcon);
3469
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003470 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003471}
3472
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003473static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3474{
3475 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3476 struct hci_conn *hcon;
3477 struct hci_chan *hchan;
3478 struct amp_mgr *mgr;
3479
3480 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3481 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3482 ev->status);
3483
3484 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3485 if (!hcon)
3486 return;
3487
3488 /* Create AMP hchan */
3489 hchan = hci_chan_create(hcon);
3490 if (!hchan)
3491 return;
3492
3493 hchan->handle = le16_to_cpu(ev->handle);
3494
3495 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3496
3497 mgr = hcon->amp_mgr;
3498 if (mgr && mgr->bredr_chan) {
3499 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3500
3501 l2cap_chan_lock(bredr_chan);
3502
3503 bredr_chan->conn->mtu = hdev->block_mtu;
3504 l2cap_logical_cfm(bredr_chan, hchan, 0);
3505 hci_conn_hold(hcon);
3506
3507 l2cap_chan_unlock(bredr_chan);
3508 }
3509}
3510
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003511static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3512 struct sk_buff *skb)
3513{
3514 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3515 struct hci_chan *hchan;
3516
3517 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3518 le16_to_cpu(ev->handle), ev->status);
3519
3520 if (ev->status)
3521 return;
3522
3523 hci_dev_lock(hdev);
3524
3525 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3526 if (!hchan)
3527 goto unlock;
3528
3529 amp_destroy_logical_link(hchan, ev->reason);
3530
3531unlock:
3532 hci_dev_unlock(hdev);
3533}
3534
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003535static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3536 struct sk_buff *skb)
3537{
3538 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3539 struct hci_conn *hcon;
3540
3541 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3542
3543 if (ev->status)
3544 return;
3545
3546 hci_dev_lock(hdev);
3547
3548 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3549 if (hcon) {
3550 hcon->state = BT_CLOSED;
3551 hci_conn_del(hcon);
3552 }
3553
3554 hci_dev_unlock(hdev);
3555}
3556
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003557static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003558{
3559 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3560 struct hci_conn *conn;
3561
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003562 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003563
3564 hci_dev_lock(hdev);
3565
Andre Guedesb47a09b2012-07-27 15:10:15 -03003566 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003567 if (!conn) {
3568 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3569 if (!conn) {
3570 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003571 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003572 }
Andre Guedes29b79882011-05-31 14:20:54 -03003573
3574 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003575
Marcel Holtmann880be4e2013-10-13 07:25:18 -07003576 /* The advertising parameters for own address type
3577 * define which source address and source address
3578 * type this connections has.
3579 */
3580 if (bacmp(&conn->src, BDADDR_ANY)) {
3581 conn->src_type = ADDR_LE_DEV_PUBLIC;
3582 } else {
3583 bacpy(&conn->src, &hdev->static_addr);
3584 conn->src_type = ADDR_LE_DEV_RANDOM;
3585 }
3586
Andre Guedesb9b343d2012-07-27 15:10:11 -03003587 if (ev->role == LE_CONN_ROLE_MASTER) {
3588 conn->out = true;
3589 conn->link_mode |= HCI_LM_MASTER;
3590 }
Ville Tervob62f3282011-02-10 22:38:50 -03003591 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003592
Andre Guedescd17dec2012-07-27 15:10:16 -03003593 if (ev->status) {
3594 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3595 conn->dst_type, ev->status);
3596 hci_proto_connect_cfm(conn, ev->status);
3597 conn->state = BT_CLOSED;
3598 hci_conn_del(conn);
3599 goto unlock;
3600 }
3601
Johan Hedbergb644ba32012-01-17 21:48:47 +02003602 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3603 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003604 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003605
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003606 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003607 conn->handle = __le16_to_cpu(ev->handle);
3608 conn->state = BT_CONNECTED;
3609
Jukka Rissanen18722c22013-12-11 17:05:37 +02003610 if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
3611 set_bit(HCI_CONN_6LOWPAN, &conn->flags);
3612
Ville Tervofcd89c02011-02-10 22:38:47 -03003613 hci_conn_add_sysfs(conn);
3614
3615 hci_proto_connect_cfm(conn, ev->status);
3616
3617unlock:
3618 hci_dev_unlock(hdev);
3619}
3620
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003621static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003622{
Andre Guedese95beb42011-09-26 20:48:35 -03003623 u8 num_reports = skb->data[0];
3624 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003625 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003626
Andre Guedese95beb42011-09-26 20:48:35 -03003627 while (num_reports--) {
3628 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003629
Andre Guedes3c9e9192012-01-10 18:20:50 -03003630 rssi = ev->data[ev->length];
3631 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003632 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003633
Andre Guedese95beb42011-09-26 20:48:35 -03003634 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003635 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003636}
3637
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003638static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003639{
3640 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3641 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003642 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003643 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003644 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003645
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003646 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003647
3648 hci_dev_lock(hdev);
3649
3650 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003651 if (conn == NULL)
3652 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003653
Johan Hedberg98a0b842014-01-30 19:40:00 -08003654 ltk = hci_find_ltk(hdev, ev->ediv, ev->random, conn->out);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003655 if (ltk == NULL)
3656 goto not_found;
3657
3658 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003659 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003660
3661 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03003662 conn->pending_sec_level = BT_SECURITY_HIGH;
3663 else
3664 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003665
Andre Guedes89cbb4d2013-07-31 16:25:29 -03003666 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003667
3668 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3669
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003670 if (ltk->type & HCI_SMP_STK) {
3671 list_del(&ltk->list);
3672 kfree(ltk);
3673 }
3674
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003675 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003676
3677 return;
3678
3679not_found:
3680 neg.handle = ev->handle;
3681 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3682 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003683}
3684
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003685static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003686{
3687 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3688
3689 skb_pull(skb, sizeof(*le_ev));
3690
3691 switch (le_ev->subevent) {
3692 case HCI_EV_LE_CONN_COMPLETE:
3693 hci_le_conn_complete_evt(hdev, skb);
3694 break;
3695
Andre Guedes9aa04c92011-05-26 16:23:51 -03003696 case HCI_EV_LE_ADVERTISING_REPORT:
3697 hci_le_adv_report_evt(hdev, skb);
3698 break;
3699
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003700 case HCI_EV_LE_LTK_REQ:
3701 hci_le_ltk_request_evt(hdev, skb);
3702 break;
3703
Ville Tervofcd89c02011-02-10 22:38:47 -03003704 default:
3705 break;
3706 }
3707}
3708
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003709static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3710{
3711 struct hci_ev_channel_selected *ev = (void *) skb->data;
3712 struct hci_conn *hcon;
3713
3714 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3715
3716 skb_pull(skb, sizeof(*ev));
3717
3718 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3719 if (!hcon)
3720 return;
3721
3722 amp_read_loc_assoc_final_data(hdev, hcon);
3723}
3724
Linus Torvalds1da177e2005-04-16 15:20:36 -07003725void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3726{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003727 struct hci_event_hdr *hdr = (void *) skb->data;
3728 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003729
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003730 hci_dev_lock(hdev);
3731
3732 /* Received events are (currently) only needed when a request is
3733 * ongoing so avoid unnecessary memory allocation.
3734 */
3735 if (hdev->req_status == HCI_REQ_PEND) {
3736 kfree_skb(hdev->recv_evt);
3737 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3738 }
3739
3740 hci_dev_unlock(hdev);
3741
Linus Torvalds1da177e2005-04-16 15:20:36 -07003742 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3743
Johan Hedberg02350a72013-04-03 21:50:29 +03003744 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02003745 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
3746 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03003747
3748 hci_req_cmd_complete(hdev, opcode, 0);
3749 }
3750
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003751 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003752 case HCI_EV_INQUIRY_COMPLETE:
3753 hci_inquiry_complete_evt(hdev, skb);
3754 break;
3755
3756 case HCI_EV_INQUIRY_RESULT:
3757 hci_inquiry_result_evt(hdev, skb);
3758 break;
3759
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003760 case HCI_EV_CONN_COMPLETE:
3761 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003762 break;
3763
Linus Torvalds1da177e2005-04-16 15:20:36 -07003764 case HCI_EV_CONN_REQUEST:
3765 hci_conn_request_evt(hdev, skb);
3766 break;
3767
Linus Torvalds1da177e2005-04-16 15:20:36 -07003768 case HCI_EV_DISCONN_COMPLETE:
3769 hci_disconn_complete_evt(hdev, skb);
3770 break;
3771
Linus Torvalds1da177e2005-04-16 15:20:36 -07003772 case HCI_EV_AUTH_COMPLETE:
3773 hci_auth_complete_evt(hdev, skb);
3774 break;
3775
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003776 case HCI_EV_REMOTE_NAME:
3777 hci_remote_name_evt(hdev, skb);
3778 break;
3779
Linus Torvalds1da177e2005-04-16 15:20:36 -07003780 case HCI_EV_ENCRYPT_CHANGE:
3781 hci_encrypt_change_evt(hdev, skb);
3782 break;
3783
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003784 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3785 hci_change_link_key_complete_evt(hdev, skb);
3786 break;
3787
3788 case HCI_EV_REMOTE_FEATURES:
3789 hci_remote_features_evt(hdev, skb);
3790 break;
3791
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003792 case HCI_EV_CMD_COMPLETE:
3793 hci_cmd_complete_evt(hdev, skb);
3794 break;
3795
3796 case HCI_EV_CMD_STATUS:
3797 hci_cmd_status_evt(hdev, skb);
3798 break;
3799
3800 case HCI_EV_ROLE_CHANGE:
3801 hci_role_change_evt(hdev, skb);
3802 break;
3803
3804 case HCI_EV_NUM_COMP_PKTS:
3805 hci_num_comp_pkts_evt(hdev, skb);
3806 break;
3807
3808 case HCI_EV_MODE_CHANGE:
3809 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003810 break;
3811
3812 case HCI_EV_PIN_CODE_REQ:
3813 hci_pin_code_request_evt(hdev, skb);
3814 break;
3815
3816 case HCI_EV_LINK_KEY_REQ:
3817 hci_link_key_request_evt(hdev, skb);
3818 break;
3819
3820 case HCI_EV_LINK_KEY_NOTIFY:
3821 hci_link_key_notify_evt(hdev, skb);
3822 break;
3823
3824 case HCI_EV_CLOCK_OFFSET:
3825 hci_clock_offset_evt(hdev, skb);
3826 break;
3827
Marcel Holtmanna8746412008-07-14 20:13:46 +02003828 case HCI_EV_PKT_TYPE_CHANGE:
3829 hci_pkt_type_change_evt(hdev, skb);
3830 break;
3831
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003832 case HCI_EV_PSCAN_REP_MODE:
3833 hci_pscan_rep_mode_evt(hdev, skb);
3834 break;
3835
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003836 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3837 hci_inquiry_result_with_rssi_evt(hdev, skb);
3838 break;
3839
3840 case HCI_EV_REMOTE_EXT_FEATURES:
3841 hci_remote_ext_features_evt(hdev, skb);
3842 break;
3843
3844 case HCI_EV_SYNC_CONN_COMPLETE:
3845 hci_sync_conn_complete_evt(hdev, skb);
3846 break;
3847
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003848 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3849 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003850 break;
3851
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003852 case HCI_EV_KEY_REFRESH_COMPLETE:
3853 hci_key_refresh_complete_evt(hdev, skb);
3854 break;
3855
Marcel Holtmann04936842008-07-14 20:13:48 +02003856 case HCI_EV_IO_CAPA_REQUEST:
3857 hci_io_capa_request_evt(hdev, skb);
3858 break;
3859
Johan Hedberg03b555e2011-01-04 15:40:05 +02003860 case HCI_EV_IO_CAPA_REPLY:
3861 hci_io_capa_reply_evt(hdev, skb);
3862 break;
3863
Johan Hedberga5c29682011-02-19 12:05:57 -03003864 case HCI_EV_USER_CONFIRM_REQUEST:
3865 hci_user_confirm_request_evt(hdev, skb);
3866 break;
3867
Brian Gix1143d452011-11-23 08:28:34 -08003868 case HCI_EV_USER_PASSKEY_REQUEST:
3869 hci_user_passkey_request_evt(hdev, skb);
3870 break;
3871
Johan Hedberg92a25252012-09-06 18:39:26 +03003872 case HCI_EV_USER_PASSKEY_NOTIFY:
3873 hci_user_passkey_notify_evt(hdev, skb);
3874 break;
3875
3876 case HCI_EV_KEYPRESS_NOTIFY:
3877 hci_keypress_notify_evt(hdev, skb);
3878 break;
3879
Marcel Holtmann04936842008-07-14 20:13:48 +02003880 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3881 hci_simple_pair_complete_evt(hdev, skb);
3882 break;
3883
Marcel Holtmann41a96212008-07-14 20:13:48 +02003884 case HCI_EV_REMOTE_HOST_FEATURES:
3885 hci_remote_host_features_evt(hdev, skb);
3886 break;
3887
Ville Tervofcd89c02011-02-10 22:38:47 -03003888 case HCI_EV_LE_META:
3889 hci_le_meta_evt(hdev, skb);
3890 break;
3891
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003892 case HCI_EV_CHANNEL_SELECTED:
3893 hci_chan_selected_evt(hdev, skb);
3894 break;
3895
Szymon Janc2763eda2011-03-22 13:12:22 +01003896 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3897 hci_remote_oob_data_request_evt(hdev, skb);
3898 break;
3899
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003900 case HCI_EV_PHY_LINK_COMPLETE:
3901 hci_phy_link_complete_evt(hdev, skb);
3902 break;
3903
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003904 case HCI_EV_LOGICAL_LINK_COMPLETE:
3905 hci_loglink_complete_evt(hdev, skb);
3906 break;
3907
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003908 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3909 hci_disconn_loglink_complete_evt(hdev, skb);
3910 break;
3911
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003912 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3913 hci_disconn_phylink_complete_evt(hdev, skb);
3914 break;
3915
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003916 case HCI_EV_NUM_COMP_BLOCKS:
3917 hci_num_comp_blocks_evt(hdev, skb);
3918 break;
3919
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003920 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003921 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003922 break;
3923 }
3924
3925 kfree_skb(skb);
3926 hdev->stat.evt_rx++;
3927}