blob: e71c98fedc9b79da3b1b6647a4f4e6af8d56e972 [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 Holtmanna9de9242007-10-20 13:33:56 +0200201}
202
203static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
204{
205 __u8 status = *((__u8 *) skb->data);
206 void *sent;
207
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300208 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200209
210 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
211 if (!sent)
212 return;
213
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200214 hci_dev_lock(hdev);
215
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200216 if (test_bit(HCI_MGMT, &hdev->dev_flags))
217 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200218 else if (!status)
219 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200220
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200221 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200222}
223
224static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
225{
226 struct hci_rp_read_local_name *rp = (void *) skb->data;
227
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300228 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200229
230 if (rp->status)
231 return;
232
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200233 if (test_bit(HCI_SETUP, &hdev->dev_flags))
234 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200235}
236
237static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
238{
239 __u8 status = *((__u8 *) skb->data);
240 void *sent;
241
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300242 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200243
244 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
245 if (!sent)
246 return;
247
248 if (!status) {
249 __u8 param = *((__u8 *) sent);
250
251 if (param == AUTH_ENABLED)
252 set_bit(HCI_AUTH, &hdev->flags);
253 else
254 clear_bit(HCI_AUTH, &hdev->flags);
255 }
256
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200257 if (test_bit(HCI_MGMT, &hdev->dev_flags))
258 mgmt_auth_enable_complete(hdev, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200259}
260
261static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
262{
263 __u8 status = *((__u8 *) skb->data);
264 void *sent;
265
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300266 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200267
268 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
269 if (!sent)
270 return;
271
272 if (!status) {
273 __u8 param = *((__u8 *) sent);
274
275 if (param)
276 set_bit(HCI_ENCRYPT, &hdev->flags);
277 else
278 clear_bit(HCI_ENCRYPT, &hdev->flags);
279 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200280}
281
282static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
283{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200284 __u8 param, status = *((__u8 *) skb->data);
285 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200286 void *sent;
287
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300288 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200289
290 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
291 if (!sent)
292 return;
293
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200294 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200295
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200296 hci_dev_lock(hdev);
297
Mikel Astizfa1bd912012-08-09 09:52:29 +0200298 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200299 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200300 hdev->discov_timeout = 0;
301 goto done;
302 }
303
Johan Hedberg0663ca22013-10-02 13:43:14 +0300304 /* We need to ensure that we set this back on if someone changed
305 * the scan mode through a raw HCI socket.
306 */
307 set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
308
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200309 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
310 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200311
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200312 if (param & SCAN_INQUIRY) {
313 set_bit(HCI_ISCAN, &hdev->flags);
314 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200315 mgmt_discoverable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200316 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200317 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200318
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200319 if (param & SCAN_PAGE) {
320 set_bit(HCI_PSCAN, &hdev->flags);
321 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200322 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200323 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200324 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200325
326done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200327 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200328}
329
330static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
331{
332 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
333
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300334 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200335
336 if (rp->status)
337 return;
338
339 memcpy(hdev->dev_class, rp->dev_class, 3);
340
341 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300342 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200343}
344
345static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
346{
347 __u8 status = *((__u8 *) skb->data);
348 void *sent;
349
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300350 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200351
352 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
353 if (!sent)
354 return;
355
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100356 hci_dev_lock(hdev);
357
358 if (status == 0)
359 memcpy(hdev->dev_class, sent, 3);
360
361 if (test_bit(HCI_MGMT, &hdev->dev_flags))
362 mgmt_set_class_of_dev_complete(hdev, sent, status);
363
364 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200365}
366
367static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
368{
369 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200371
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300372 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200373
374 if (rp->status)
375 return;
376
377 setting = __le16_to_cpu(rp->voice_setting);
378
Marcel Holtmannf383f272008-07-14 20:13:47 +0200379 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200380 return;
381
382 hdev->voice_setting = setting;
383
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300384 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200385
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200386 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200387 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200388}
389
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300390static void hci_cc_write_voice_setting(struct hci_dev *hdev,
391 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392{
393 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200394 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 void *sent;
396
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300397 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398
Marcel Holtmannf383f272008-07-14 20:13:47 +0200399 if (status)
400 return;
401
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200402 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
403 if (!sent)
404 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405
Marcel Holtmannf383f272008-07-14 20:13:47 +0200406 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
Marcel Holtmannf383f272008-07-14 20:13:47 +0200408 if (hdev->voice_setting == setting)
409 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410
Marcel Holtmannf383f272008-07-14 20:13:47 +0200411 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300413 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200414
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200415 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200416 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417}
418
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -0700419static void hci_cc_read_num_supported_iac(struct hci_dev *hdev,
420 struct sk_buff *skb)
421{
422 struct hci_rp_read_num_supported_iac *rp = (void *) skb->data;
423
424 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
425
426 if (rp->status)
427 return;
428
429 hdev->num_iac = rp->num_iac;
430
431 BT_DBG("%s num iac %d", hdev->name, hdev->num_iac);
432}
433
Marcel Holtmann333140b2008-07-14 20:13:48 +0200434static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
435{
436 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300437 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200438
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300439 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200440
Marcel Holtmann333140b2008-07-14 20:13:48 +0200441 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
442 if (!sent)
443 return;
444
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300445 if (!status) {
446 if (sent->mode)
Johan Hedbergcad718e2013-04-17 15:00:51 +0300447 hdev->features[1][0] |= LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300448 else
Johan Hedbergcad718e2013-04-17 15:00:51 +0300449 hdev->features[1][0] &= ~LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300450 }
451
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200452 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300453 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200454 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300455 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200456 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
457 else
458 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
459 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200460}
461
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200462static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
463{
464 struct hci_rp_read_local_version *rp = (void *) skb->data;
465
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300466 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200467
468 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200469 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200470
471 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200472 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200473 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200474 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200475 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200476
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300477 BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300478 hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200479}
480
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300481static void hci_cc_read_local_commands(struct hci_dev *hdev,
482 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200483{
484 struct hci_rp_read_local_commands *rp = (void *) skb->data;
485
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300486 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200487
Johan Hedberg2177bab2013-03-05 20:37:43 +0200488 if (!rp->status)
489 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200490}
491
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300492static void hci_cc_read_local_features(struct hci_dev *hdev,
493 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200494{
495 struct hci_rp_read_local_features *rp = (void *) skb->data;
496
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300497 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200498
499 if (rp->status)
500 return;
501
502 memcpy(hdev->features, rp->features, 8);
503
504 /* Adjust default settings according to features
505 * supported by device. */
506
Johan Hedbergcad718e2013-04-17 15:00:51 +0300507 if (hdev->features[0][0] & LMP_3SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200508 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
509
Johan Hedbergcad718e2013-04-17 15:00:51 +0300510 if (hdev->features[0][0] & LMP_5SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200511 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
512
Johan Hedbergcad718e2013-04-17 15:00:51 +0300513 if (hdev->features[0][1] & LMP_HV2) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200514 hdev->pkt_type |= (HCI_HV2);
515 hdev->esco_type |= (ESCO_HV2);
516 }
517
Johan Hedbergcad718e2013-04-17 15:00:51 +0300518 if (hdev->features[0][1] & LMP_HV3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200519 hdev->pkt_type |= (HCI_HV3);
520 hdev->esco_type |= (ESCO_HV3);
521 }
522
Andre Guedes45db810f2012-07-24 15:03:49 -0300523 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200524 hdev->esco_type |= (ESCO_EV3);
525
Johan Hedbergcad718e2013-04-17 15:00:51 +0300526 if (hdev->features[0][4] & LMP_EV4)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200527 hdev->esco_type |= (ESCO_EV4);
528
Johan Hedbergcad718e2013-04-17 15:00:51 +0300529 if (hdev->features[0][4] & LMP_EV5)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200530 hdev->esco_type |= (ESCO_EV5);
531
Johan Hedbergcad718e2013-04-17 15:00:51 +0300532 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100533 hdev->esco_type |= (ESCO_2EV3);
534
Johan Hedbergcad718e2013-04-17 15:00:51 +0300535 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100536 hdev->esco_type |= (ESCO_3EV3);
537
Johan Hedbergcad718e2013-04-17 15:00:51 +0300538 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100539 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
540
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200541 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
Johan Hedbergcad718e2013-04-17 15:00:51 +0300542 hdev->features[0][0], hdev->features[0][1],
543 hdev->features[0][2], hdev->features[0][3],
544 hdev->features[0][4], hdev->features[0][5],
545 hdev->features[0][6], hdev->features[0][7]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200546}
547
Andre Guedes971e3a42011-06-30 19:20:52 -0300548static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300549 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300550{
551 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
552
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300553 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300554
555 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200556 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300557
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300558 hdev->max_page = rp->max_page;
559
Johan Hedbergcad718e2013-04-17 15:00:51 +0300560 if (rp->page < HCI_MAX_PAGES)
561 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300562}
563
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200564static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300565 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200566{
567 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
568
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300569 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200570
Johan Hedberg42c6b122013-03-05 20:37:49 +0200571 if (!rp->status)
572 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200573}
574
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200575static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
576{
577 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
578
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300579 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200580
581 if (rp->status)
582 return;
583
584 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
585 hdev->sco_mtu = rp->sco_mtu;
586 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
587 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
588
589 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
590 hdev->sco_mtu = 64;
591 hdev->sco_pkts = 8;
592 }
593
594 hdev->acl_cnt = hdev->acl_pkts;
595 hdev->sco_cnt = hdev->sco_pkts;
596
Gustavo Padovan807deac2012-05-17 00:36:24 -0300597 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
598 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200599}
600
601static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
602{
603 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
604
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300605 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200606
607 if (!rp->status)
608 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200609}
610
Johan Hedbergf332ec62013-03-15 17:07:11 -0500611static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
612 struct sk_buff *skb)
613{
614 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
615
616 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
617
618 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
619 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
620 hdev->page_scan_window = __le16_to_cpu(rp->window);
621 }
622}
623
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500624static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
625 struct sk_buff *skb)
626{
627 u8 status = *((u8 *) skb->data);
628 struct hci_cp_write_page_scan_activity *sent;
629
630 BT_DBG("%s status 0x%2.2x", hdev->name, status);
631
632 if (status)
633 return;
634
635 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
636 if (!sent)
637 return;
638
639 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
640 hdev->page_scan_window = __le16_to_cpu(sent->window);
641}
642
Johan Hedbergf332ec62013-03-15 17:07:11 -0500643static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
644 struct sk_buff *skb)
645{
646 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
647
648 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
649
650 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
651 hdev->page_scan_type = rp->type;
652}
653
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500654static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
655 struct sk_buff *skb)
656{
657 u8 status = *((u8 *) skb->data);
658 u8 *type;
659
660 BT_DBG("%s status 0x%2.2x", hdev->name, status);
661
662 if (status)
663 return;
664
665 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
666 if (type)
667 hdev->page_scan_type = *type;
668}
669
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200670static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300671 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200672{
673 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
674
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300675 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200676
677 if (rp->status)
678 return;
679
680 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
681 hdev->block_len = __le16_to_cpu(rp->block_len);
682 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
683
684 hdev->block_cnt = hdev->num_blocks;
685
686 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300687 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200688}
689
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300690static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300691 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300692{
693 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
694
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300695 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300696
697 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300698 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300699
700 hdev->amp_status = rp->amp_status;
701 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
702 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
703 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
704 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
705 hdev->amp_type = rp->amp_type;
706 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
707 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
708 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
709 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
710
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300711a2mp_rsp:
712 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300713}
714
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300715static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
716 struct sk_buff *skb)
717{
718 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
719 struct amp_assoc *assoc = &hdev->loc_assoc;
720 size_t rem_len, frag_len;
721
722 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
723
724 if (rp->status)
725 goto a2mp_rsp;
726
727 frag_len = skb->len - sizeof(*rp);
728 rem_len = __le16_to_cpu(rp->rem_len);
729
730 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300731 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300732
733 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
734 assoc->offset += frag_len;
735
736 /* Read other fragments */
737 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
738
739 return;
740 }
741
742 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
743 assoc->len = assoc->offset + rem_len;
744 assoc->offset = 0;
745
746a2mp_rsp:
747 /* Send A2MP Rsp when all fragments are received */
748 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300749 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300750}
751
Johan Hedbergd5859e22011-01-25 01:19:58 +0200752static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300753 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200754{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700755 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200756
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300757 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200758
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700759 if (!rp->status)
760 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200761}
762
Johan Hedberg980e1a52011-01-22 06:10:07 +0200763static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
764{
765 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
766 struct hci_cp_pin_code_reply *cp;
767 struct hci_conn *conn;
768
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300769 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200770
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200771 hci_dev_lock(hdev);
772
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200773 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200774 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200775
Mikel Astizfa1bd912012-08-09 09:52:29 +0200776 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200777 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200778
779 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
780 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200781 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200782
783 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
784 if (conn)
785 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200786
787unlock:
788 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200789}
790
791static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
792{
793 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
794
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300795 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200796
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200797 hci_dev_lock(hdev);
798
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200799 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200800 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300801 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200802
803 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200804}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200805
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300806static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
807 struct sk_buff *skb)
808{
809 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
810
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300811 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300812
813 if (rp->status)
814 return;
815
816 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
817 hdev->le_pkts = rp->le_max_pkt;
818
819 hdev->le_cnt = hdev->le_pkts;
820
821 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300822}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200823
Johan Hedberg60e77322013-01-22 14:01:59 +0200824static void hci_cc_le_read_local_features(struct hci_dev *hdev,
825 struct sk_buff *skb)
826{
827 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
828
829 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
830
831 if (!rp->status)
832 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200833}
834
Johan Hedberg8fa19092012-10-19 20:57:49 +0300835static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
836 struct sk_buff *skb)
837{
838 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
839
840 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
841
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500842 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300843 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300844}
845
Johan Hedberga5c29682011-02-19 12:05:57 -0300846static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
847{
848 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
849
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300850 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300851
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200852 hci_dev_lock(hdev);
853
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200854 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300855 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
856 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200857
858 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300859}
860
861static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300862 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300863{
864 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
865
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300866 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300867
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200868 hci_dev_lock(hdev);
869
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200870 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200871 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300872 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200873
874 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300875}
876
Brian Gix1143d452011-11-23 08:28:34 -0800877static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
878{
879 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
880
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300881 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800882
883 hci_dev_lock(hdev);
884
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200885 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200886 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300887 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800888
889 hci_dev_unlock(hdev);
890}
891
892static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300893 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800894{
895 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
896
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300897 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800898
899 hci_dev_lock(hdev);
900
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200901 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800902 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300903 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800904
905 hci_dev_unlock(hdev);
906}
907
Szymon Jancc35938b2011-03-22 13:12:21 +0100908static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300909 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100910{
911 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
912
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300913 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100914
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200915 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +0200916 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +0100917 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200918 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100919}
920
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100921static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
922{
923 __u8 *sent, status = *((__u8 *) skb->data);
924
925 BT_DBG("%s status 0x%2.2x", hdev->name, status);
926
927 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
928 if (!sent)
929 return;
930
931 hci_dev_lock(hdev);
932
933 if (!status) {
934 if (*sent)
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200935 set_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100936 else
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200937 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100938 }
939
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500940 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100941}
942
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300943static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300944 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300945{
946 struct hci_cp_le_set_scan_enable *cp;
947 __u8 status = *((__u8 *) skb->data);
948
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300949 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300950
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300951 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
952 if (!cp)
953 return;
954
Andre Guedes3fd319b2013-04-30 15:29:36 -0300955 if (status)
956 return;
957
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200958 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -0300959 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300960 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200961 break;
962
Andre Guedes76a388b2013-04-04 20:21:02 -0300963 case LE_SCAN_DISABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300964 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200965 break;
966
967 default:
968 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
969 break;
Andre Guedes35815082011-05-26 16:23:53 -0300970 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300971}
972
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200973static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
974 struct sk_buff *skb)
975{
976 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
977
978 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
979
980 if (!rp->status)
981 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200982}
983
Johan Hedberg9b008c02013-01-22 14:02:01 +0200984static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
985 struct sk_buff *skb)
986{
987 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
988
989 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
990
991 if (!rp->status)
992 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +0200993}
994
Gustavo Padovan6039aa72012-05-23 04:04:18 -0300995static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
996 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -0300997{
Johan Hedberg06199cf2012-02-22 16:37:11 +0200998 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -0300999 __u8 status = *((__u8 *) skb->data);
1000
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001001 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001002
Johan Hedberg06199cf2012-02-22 16:37:11 +02001003 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001004 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001005 return;
1006
Johan Hedberg8f984df2012-02-28 01:07:22 +02001007 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001008 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001009 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001010 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1011 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001012 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001013 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001014 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001015 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001016
1017 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001018 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001019 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001020 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001021 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001022}
1023
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001024static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1025 struct sk_buff *skb)
1026{
1027 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1028
1029 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1030 hdev->name, rp->status, rp->phy_handle);
1031
1032 if (rp->status)
1033 return;
1034
1035 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1036}
1037
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001038static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001039{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001040 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001041
1042 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001043 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001044 return;
1045 }
1046
Andre Guedes89352e72011-11-04 14:16:53 -03001047 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001048}
1049
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001050static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001052 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001055 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001056
1057 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 if (!cp)
1059 return;
1060
1061 hci_dev_lock(hdev);
1062
1063 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1064
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001065 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066
1067 if (status) {
1068 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001069 if (status != 0x0c || conn->attempt > 2) {
1070 conn->state = BT_CLOSED;
1071 hci_proto_connect_cfm(conn, status);
1072 hci_conn_del(conn);
1073 } else
1074 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 }
1076 } else {
1077 if (!conn) {
1078 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1079 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001080 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081 conn->link_mode |= HCI_LM_MASTER;
1082 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001083 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084 }
1085 }
1086
1087 hci_dev_unlock(hdev);
1088}
1089
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001090static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001092 struct hci_cp_add_sco *cp;
1093 struct hci_conn *acl, *sco;
1094 __u16 handle;
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 Holtmannb6a0dc82007-10-20 14:55:10 +02001097
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001098 if (!status)
1099 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001101 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1102 if (!cp)
1103 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001105 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001107 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001108
1109 hci_dev_lock(hdev);
1110
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001111 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001112 if (acl) {
1113 sco = acl->link;
1114 if (sco) {
1115 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001116
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001117 hci_proto_connect_cfm(sco, status);
1118 hci_conn_del(sco);
1119 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001120 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001121
1122 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123}
1124
Marcel Holtmannf8558552008-07-14 20:13:49 +02001125static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1126{
1127 struct hci_cp_auth_requested *cp;
1128 struct hci_conn *conn;
1129
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001130 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001131
1132 if (!status)
1133 return;
1134
1135 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1136 if (!cp)
1137 return;
1138
1139 hci_dev_lock(hdev);
1140
1141 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1142 if (conn) {
1143 if (conn->state == BT_CONFIG) {
1144 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001145 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001146 }
1147 }
1148
1149 hci_dev_unlock(hdev);
1150}
1151
1152static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1153{
1154 struct hci_cp_set_conn_encrypt *cp;
1155 struct hci_conn *conn;
1156
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001157 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001158
1159 if (!status)
1160 return;
1161
1162 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1163 if (!cp)
1164 return;
1165
1166 hci_dev_lock(hdev);
1167
1168 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1169 if (conn) {
1170 if (conn->state == BT_CONFIG) {
1171 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001172 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001173 }
1174 }
1175
1176 hci_dev_unlock(hdev);
1177}
1178
Johan Hedberg127178d2010-11-18 22:22:29 +02001179static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001180 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001181{
Johan Hedberg392599b2010-11-18 22:22:28 +02001182 if (conn->state != BT_CONFIG || !conn->out)
1183 return 0;
1184
Johan Hedberg765c2a92011-01-19 12:06:52 +05301185 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001186 return 0;
1187
1188 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001189 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001190 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1191 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001192 return 0;
1193
Johan Hedberg392599b2010-11-18 22:22:28 +02001194 return 1;
1195}
1196
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001197static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001198 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001199{
1200 struct hci_cp_remote_name_req cp;
1201
1202 memset(&cp, 0, sizeof(cp));
1203
1204 bacpy(&cp.bdaddr, &e->data.bdaddr);
1205 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1206 cp.pscan_mode = e->data.pscan_mode;
1207 cp.clock_offset = e->data.clock_offset;
1208
1209 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1210}
1211
Johan Hedbergb644ba32012-01-17 21:48:47 +02001212static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001213{
1214 struct discovery_state *discov = &hdev->discovery;
1215 struct inquiry_entry *e;
1216
Johan Hedbergb644ba32012-01-17 21:48:47 +02001217 if (list_empty(&discov->resolve))
1218 return false;
1219
1220 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001221 if (!e)
1222 return false;
1223
Johan Hedbergb644ba32012-01-17 21:48:47 +02001224 if (hci_resolve_name(hdev, e) == 0) {
1225 e->name_state = NAME_PENDING;
1226 return true;
1227 }
1228
1229 return false;
1230}
1231
1232static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001233 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001234{
1235 struct discovery_state *discov = &hdev->discovery;
1236 struct inquiry_entry *e;
1237
1238 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001239 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1240 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001241
1242 if (discov->state == DISCOVERY_STOPPED)
1243 return;
1244
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001245 if (discov->state == DISCOVERY_STOPPING)
1246 goto discov_complete;
1247
1248 if (discov->state != DISCOVERY_RESOLVING)
1249 return;
1250
1251 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001252 /* If the device was not found in a list of found devices names of which
1253 * are pending. there is no need to continue resolving a next name as it
1254 * will be done upon receiving another Remote Name Request Complete
1255 * Event */
1256 if (!e)
1257 return;
1258
1259 list_del(&e->list);
1260 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001261 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001262 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1263 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001264 } else {
1265 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001266 }
1267
Johan Hedbergb644ba32012-01-17 21:48:47 +02001268 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001269 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001270
1271discov_complete:
1272 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1273}
1274
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001275static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1276{
Johan Hedberg127178d2010-11-18 22:22:29 +02001277 struct hci_cp_remote_name_req *cp;
1278 struct hci_conn *conn;
1279
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001280 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001281
1282 /* If successful wait for the name req complete event before
1283 * checking for the need to do authentication */
1284 if (!status)
1285 return;
1286
1287 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1288 if (!cp)
1289 return;
1290
1291 hci_dev_lock(hdev);
1292
1293 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001294
1295 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1296 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1297
Johan Hedberg79c6c702011-04-28 11:28:55 -07001298 if (!conn)
1299 goto unlock;
1300
1301 if (!hci_outgoing_auth_needed(hdev, conn))
1302 goto unlock;
1303
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001304 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001305 struct hci_cp_auth_requested auth_cp;
1306
1307 auth_cp.handle = __cpu_to_le16(conn->handle);
1308 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1309 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001310 }
1311
Johan Hedberg79c6c702011-04-28 11:28:55 -07001312unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001313 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001314}
1315
Marcel Holtmann769be972008-07-14 20:13:49 +02001316static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1317{
1318 struct hci_cp_read_remote_features *cp;
1319 struct hci_conn *conn;
1320
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001321 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001322
1323 if (!status)
1324 return;
1325
1326 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1327 if (!cp)
1328 return;
1329
1330 hci_dev_lock(hdev);
1331
1332 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1333 if (conn) {
1334 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001335 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001336 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001337 }
1338 }
1339
1340 hci_dev_unlock(hdev);
1341}
1342
1343static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1344{
1345 struct hci_cp_read_remote_ext_features *cp;
1346 struct hci_conn *conn;
1347
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001348 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001349
1350 if (!status)
1351 return;
1352
1353 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1354 if (!cp)
1355 return;
1356
1357 hci_dev_lock(hdev);
1358
1359 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1360 if (conn) {
1361 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001362 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001363 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001364 }
1365 }
1366
1367 hci_dev_unlock(hdev);
1368}
1369
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001370static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1371{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001372 struct hci_cp_setup_sync_conn *cp;
1373 struct hci_conn *acl, *sco;
1374 __u16 handle;
1375
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001376 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001377
1378 if (!status)
1379 return;
1380
1381 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1382 if (!cp)
1383 return;
1384
1385 handle = __le16_to_cpu(cp->handle);
1386
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001387 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001388
1389 hci_dev_lock(hdev);
1390
1391 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001392 if (acl) {
1393 sco = acl->link;
1394 if (sco) {
1395 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001396
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001397 hci_proto_connect_cfm(sco, status);
1398 hci_conn_del(sco);
1399 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001400 }
1401
1402 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001403}
1404
1405static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1406{
1407 struct hci_cp_sniff_mode *cp;
1408 struct hci_conn *conn;
1409
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001410 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001411
1412 if (!status)
1413 return;
1414
1415 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1416 if (!cp)
1417 return;
1418
1419 hci_dev_lock(hdev);
1420
1421 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001422 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001423 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001424
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001425 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001426 hci_sco_setup(conn, status);
1427 }
1428
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001429 hci_dev_unlock(hdev);
1430}
1431
1432static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1433{
1434 struct hci_cp_exit_sniff_mode *cp;
1435 struct hci_conn *conn;
1436
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001437 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001438
1439 if (!status)
1440 return;
1441
1442 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1443 if (!cp)
1444 return;
1445
1446 hci_dev_lock(hdev);
1447
1448 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001449 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001450 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001451
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001452 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001453 hci_sco_setup(conn, status);
1454 }
1455
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001456 hci_dev_unlock(hdev);
1457}
1458
Johan Hedberg88c3df12012-02-09 14:27:38 +02001459static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1460{
1461 struct hci_cp_disconnect *cp;
1462 struct hci_conn *conn;
1463
1464 if (!status)
1465 return;
1466
1467 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1468 if (!cp)
1469 return;
1470
1471 hci_dev_lock(hdev);
1472
1473 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1474 if (conn)
1475 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001476 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001477
1478 hci_dev_unlock(hdev);
1479}
1480
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001481static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1482{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001483 struct hci_cp_create_phy_link *cp;
1484
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001485 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001486
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001487 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1488 if (!cp)
1489 return;
1490
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001491 hci_dev_lock(hdev);
1492
1493 if (status) {
1494 struct hci_conn *hcon;
1495
1496 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1497 if (hcon)
1498 hci_conn_del(hcon);
1499 } else {
1500 amp_write_remote_assoc(hdev, cp->phy_handle);
1501 }
1502
1503 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001504}
1505
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001506static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1507{
1508 struct hci_cp_accept_phy_link *cp;
1509
1510 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1511
1512 if (status)
1513 return;
1514
1515 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1516 if (!cp)
1517 return;
1518
1519 amp_write_remote_assoc(hdev, cp->phy_handle);
1520}
1521
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001522static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001523{
1524 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001525 struct discovery_state *discov = &hdev->discovery;
1526 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001527
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001528 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001529
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001530 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001531
1532 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1533 return;
1534
Andre Guedes3e13fa12013-03-27 20:04:56 -03001535 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1536 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1537
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001538 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001539 return;
1540
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001541 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001542
Andre Guedes343f9352012-02-17 20:39:37 -03001543 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001544 goto unlock;
1545
1546 if (list_empty(&discov->resolve)) {
1547 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1548 goto unlock;
1549 }
1550
1551 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1552 if (e && hci_resolve_name(hdev, e) == 0) {
1553 e->name_state = NAME_PENDING;
1554 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1555 } else {
1556 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1557 }
1558
1559unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001560 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001561}
1562
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001563static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001565 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001566 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 int num_rsp = *((__u8 *) skb->data);
1568
1569 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1570
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001571 if (!num_rsp)
1572 return;
1573
Andre Guedes1519cc12012-03-21 00:03:38 -03001574 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1575 return;
1576
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001578
Johan Hedberge17acd42011-03-30 23:57:16 +03001579 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001580 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001581
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582 bacpy(&data.bdaddr, &info->bdaddr);
1583 data.pscan_rep_mode = info->pscan_rep_mode;
1584 data.pscan_period_mode = info->pscan_period_mode;
1585 data.pscan_mode = info->pscan_mode;
1586 memcpy(data.dev_class, info->dev_class, 3);
1587 data.clock_offset = info->clock_offset;
1588 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001589 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001590
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001591 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001592 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001593 info->dev_class, 0, !name_known, ssp, NULL,
1594 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001596
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 hci_dev_unlock(hdev);
1598}
1599
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001600static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001602 struct hci_ev_conn_complete *ev = (void *) skb->data;
1603 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001605 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001606
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001608
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001609 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001610 if (!conn) {
1611 if (ev->link_type != SCO_LINK)
1612 goto unlock;
1613
1614 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1615 if (!conn)
1616 goto unlock;
1617
1618 conn->type = SCO_LINK;
1619 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001620
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001621 if (!ev->status) {
1622 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001623
1624 if (conn->type == ACL_LINK) {
1625 conn->state = BT_CONFIG;
1626 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001627
1628 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1629 !hci_find_link_key(hdev, &ev->bdaddr))
1630 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1631 else
1632 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001633 } else
1634 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001635
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001636 hci_conn_add_sysfs(conn);
1637
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001638 if (test_bit(HCI_AUTH, &hdev->flags))
1639 conn->link_mode |= HCI_LM_AUTH;
1640
1641 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1642 conn->link_mode |= HCI_LM_ENCRYPT;
1643
1644 /* Get remote features */
1645 if (conn->type == ACL_LINK) {
1646 struct hci_cp_read_remote_features cp;
1647 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001648 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001649 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001650 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001651
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001652 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001653 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001654 struct hci_cp_change_conn_ptype cp;
1655 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001656 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001657 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1658 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001659 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001660 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001661 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001662 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001663 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001664 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001665 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001666
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001667 if (conn->type == ACL_LINK)
1668 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001669
Marcel Holtmann769be972008-07-14 20:13:49 +02001670 if (ev->status) {
1671 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001672 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001673 } else if (ev->link_type != ACL_LINK)
1674 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001675
1676unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001678
1679 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680}
1681
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001682static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001684 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001686 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001688 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001689 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001691 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1692 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693
Szymon Janc138d22e2011-02-17 16:44:23 +01001694 if ((mask & HCI_LM_ACCEPT) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001695 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001697 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699
1700 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001701
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001702 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1703 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001704 memcpy(ie->data.dev_class, ev->dev_class, 3);
1705
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001706 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1707 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001709 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1710 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001711 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712 hci_dev_unlock(hdev);
1713 return;
1714 }
1715 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001716
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001718
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 hci_dev_unlock(hdev);
1720
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001721 if (ev->link_type == ACL_LINK ||
1722 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001723 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001724 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001726 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001728 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1729 cp.role = 0x00; /* Become master */
1730 else
1731 cp.role = 0x01; /* Remain slave */
1732
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001733 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1734 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001735 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001736 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001737 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001738
1739 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001740 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001741
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001742 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1743 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1744 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001745 cp.content_format = cpu_to_le16(hdev->voice_setting);
1746 cp.retrans_effort = 0xff;
1747
1748 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001749 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001750 } else {
1751 conn->state = BT_CONNECT2;
1752 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001753 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 } else {
1755 /* Connection rejected */
1756 struct hci_cp_reject_conn_req cp;
1757
1758 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001759 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001760 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761 }
1762}
1763
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001764static u8 hci_to_mgmt_reason(u8 err)
1765{
1766 switch (err) {
1767 case HCI_ERROR_CONNECTION_TIMEOUT:
1768 return MGMT_DEV_DISCONN_TIMEOUT;
1769 case HCI_ERROR_REMOTE_USER_TERM:
1770 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1771 case HCI_ERROR_REMOTE_POWER_OFF:
1772 return MGMT_DEV_DISCONN_REMOTE;
1773 case HCI_ERROR_LOCAL_HOST_TERM:
1774 return MGMT_DEV_DISCONN_LOCAL_HOST;
1775 default:
1776 return MGMT_DEV_DISCONN_UNKNOWN;
1777 }
1778}
1779
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001780static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001782 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001783 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001785 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 hci_dev_lock(hdev);
1788
Marcel Holtmann04837f62006-07-03 10:02:33 +02001789 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001790 if (!conn)
1791 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001792
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001793 if (ev->status == 0)
1794 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795
Johan Hedbergb644ba32012-01-17 21:48:47 +02001796 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001797 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001798 if (ev->status) {
Johan Hedberg88c3df12012-02-09 14:27:38 +02001799 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001800 conn->dst_type, ev->status);
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001801 } else {
1802 u8 reason = hci_to_mgmt_reason(ev->reason);
1803
Johan Hedbergafc747a2012-01-15 18:11:07 +02001804 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001805 conn->dst_type, reason);
1806 }
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001807 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001808
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001809 if (ev->status == 0) {
Johan Hedberg22102462013-10-05 12:01:06 +02001810 u8 type = conn->type;
1811
1812 if (type == ACL_LINK && conn->flush_key)
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301813 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001814 hci_proto_disconn_cfm(conn, ev->reason);
1815 hci_conn_del(conn);
Johan Hedberg22102462013-10-05 12:01:06 +02001816
1817 /* Re-enable advertising if necessary, since it might
1818 * have been disabled by the connection. From the
1819 * HCI_LE_Set_Advertise_Enable command description in
1820 * the core specification (v4.0):
1821 * "The Controller shall continue advertising until the Host
1822 * issues an LE_Set_Advertise_Enable command with
1823 * Advertising_Enable set to 0x00 (Advertising is disabled)
1824 * or until a connection is created or until the Advertising
1825 * is timed out due to Directed Advertising."
1826 */
1827 if (type == LE_LINK)
Marcel Holtmann5976e602013-10-06 04:08:14 -07001828 mgmt_reenable_advertising(hdev);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001829 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001830
1831unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 hci_dev_unlock(hdev);
1833}
1834
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001835static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001836{
1837 struct hci_ev_auth_complete *ev = (void *) skb->data;
1838 struct hci_conn *conn;
1839
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001840 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001841
1842 hci_dev_lock(hdev);
1843
1844 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001845 if (!conn)
1846 goto unlock;
1847
1848 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001849 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001850 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001851 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001852 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001853 conn->link_mode |= HCI_LM_AUTH;
1854 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001855 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001856 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001857 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001858 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001859 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001860
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001861 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1862 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001863
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001864 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001865 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001866 struct hci_cp_set_conn_encrypt cp;
1867 cp.handle = ev->handle;
1868 cp.encrypt = 0x01;
1869 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001870 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001871 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001872 conn->state = BT_CONNECTED;
1873 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001874 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001875 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001876 } else {
1877 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001878
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001879 hci_conn_hold(conn);
1880 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001881 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001882 }
1883
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001884 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001885 if (!ev->status) {
1886 struct hci_cp_set_conn_encrypt cp;
1887 cp.handle = ev->handle;
1888 cp.encrypt = 0x01;
1889 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001890 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001891 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001892 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001893 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001894 }
1895 }
1896
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001897unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001898 hci_dev_unlock(hdev);
1899}
1900
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001901static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001902{
Johan Hedberg127178d2010-11-18 22:22:29 +02001903 struct hci_ev_remote_name *ev = (void *) skb->data;
1904 struct hci_conn *conn;
1905
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001906 BT_DBG("%s", hdev->name);
1907
1908 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001909
1910 hci_dev_lock(hdev);
1911
1912 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001913
1914 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1915 goto check_auth;
1916
1917 if (ev->status == 0)
1918 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001919 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001920 else
1921 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1922
1923check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001924 if (!conn)
1925 goto unlock;
1926
1927 if (!hci_outgoing_auth_needed(hdev, conn))
1928 goto unlock;
1929
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001930 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001931 struct hci_cp_auth_requested cp;
1932 cp.handle = __cpu_to_le16(conn->handle);
1933 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1934 }
1935
Johan Hedberg79c6c702011-04-28 11:28:55 -07001936unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001937 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001938}
1939
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001940static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001941{
1942 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1943 struct hci_conn *conn;
1944
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001945 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001946
1947 hci_dev_lock(hdev);
1948
1949 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1950 if (conn) {
1951 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001952 if (ev->encrypt) {
1953 /* Encryption implies authentication */
1954 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001955 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001956 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001957 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001958 conn->link_mode &= ~HCI_LM_ENCRYPT;
1959 }
1960
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001961 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001962
Gustavo Padovana7d77232012-05-13 03:20:07 -03001963 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03001964 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02001965 hci_conn_drop(conn);
Gustavo Padovana7d77232012-05-13 03:20:07 -03001966 goto unlock;
1967 }
1968
Marcel Holtmannf8558552008-07-14 20:13:49 +02001969 if (conn->state == BT_CONFIG) {
1970 if (!ev->status)
1971 conn->state = BT_CONNECTED;
1972
1973 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001974 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001975 } else
1976 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001977 }
1978
Gustavo Padovana7d77232012-05-13 03:20:07 -03001979unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001980 hci_dev_unlock(hdev);
1981}
1982
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001983static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
1984 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001985{
1986 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1987 struct hci_conn *conn;
1988
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001989 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001990
1991 hci_dev_lock(hdev);
1992
1993 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1994 if (conn) {
1995 if (!ev->status)
1996 conn->link_mode |= HCI_LM_SECURE;
1997
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001998 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001999
2000 hci_key_change_cfm(conn, ev->status);
2001 }
2002
2003 hci_dev_unlock(hdev);
2004}
2005
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002006static void hci_remote_features_evt(struct hci_dev *hdev,
2007 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002008{
2009 struct hci_ev_remote_features *ev = (void *) skb->data;
2010 struct hci_conn *conn;
2011
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002012 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002013
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002014 hci_dev_lock(hdev);
2015
2016 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002017 if (!conn)
2018 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002019
Johan Hedbergccd556f2010-11-10 17:11:51 +02002020 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002021 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002022
2023 if (conn->state != BT_CONFIG)
2024 goto unlock;
2025
2026 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2027 struct hci_cp_read_remote_ext_features cp;
2028 cp.handle = ev->handle;
2029 cp.page = 0x01;
2030 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002031 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002032 goto unlock;
2033 }
2034
Johan Hedberg671267b2012-05-12 16:11:50 -03002035 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002036 struct hci_cp_remote_name_req cp;
2037 memset(&cp, 0, sizeof(cp));
2038 bacpy(&cp.bdaddr, &conn->dst);
2039 cp.pscan_rep_mode = 0x02;
2040 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002041 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2042 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002043 conn->dst_type, 0, NULL, 0,
2044 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002045
Johan Hedberg127178d2010-11-18 22:22:29 +02002046 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002047 conn->state = BT_CONNECTED;
2048 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002049 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002050 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002051
Johan Hedbergccd556f2010-11-10 17:11:51 +02002052unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002053 hci_dev_unlock(hdev);
2054}
2055
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002056static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002057{
2058 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002059 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002060 __u16 opcode;
2061
2062 skb_pull(skb, sizeof(*ev));
2063
2064 opcode = __le16_to_cpu(ev->opcode);
2065
2066 switch (opcode) {
2067 case HCI_OP_INQUIRY_CANCEL:
2068 hci_cc_inquiry_cancel(hdev, skb);
2069 break;
2070
Andre Guedes4d934832012-03-21 00:03:35 -03002071 case HCI_OP_PERIODIC_INQ:
2072 hci_cc_periodic_inq(hdev, skb);
2073 break;
2074
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002075 case HCI_OP_EXIT_PERIODIC_INQ:
2076 hci_cc_exit_periodic_inq(hdev, skb);
2077 break;
2078
2079 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2080 hci_cc_remote_name_req_cancel(hdev, skb);
2081 break;
2082
2083 case HCI_OP_ROLE_DISCOVERY:
2084 hci_cc_role_discovery(hdev, skb);
2085 break;
2086
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002087 case HCI_OP_READ_LINK_POLICY:
2088 hci_cc_read_link_policy(hdev, skb);
2089 break;
2090
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002091 case HCI_OP_WRITE_LINK_POLICY:
2092 hci_cc_write_link_policy(hdev, skb);
2093 break;
2094
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002095 case HCI_OP_READ_DEF_LINK_POLICY:
2096 hci_cc_read_def_link_policy(hdev, skb);
2097 break;
2098
2099 case HCI_OP_WRITE_DEF_LINK_POLICY:
2100 hci_cc_write_def_link_policy(hdev, skb);
2101 break;
2102
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002103 case HCI_OP_RESET:
2104 hci_cc_reset(hdev, skb);
2105 break;
2106
2107 case HCI_OP_WRITE_LOCAL_NAME:
2108 hci_cc_write_local_name(hdev, skb);
2109 break;
2110
2111 case HCI_OP_READ_LOCAL_NAME:
2112 hci_cc_read_local_name(hdev, skb);
2113 break;
2114
2115 case HCI_OP_WRITE_AUTH_ENABLE:
2116 hci_cc_write_auth_enable(hdev, skb);
2117 break;
2118
2119 case HCI_OP_WRITE_ENCRYPT_MODE:
2120 hci_cc_write_encrypt_mode(hdev, skb);
2121 break;
2122
2123 case HCI_OP_WRITE_SCAN_ENABLE:
2124 hci_cc_write_scan_enable(hdev, skb);
2125 break;
2126
2127 case HCI_OP_READ_CLASS_OF_DEV:
2128 hci_cc_read_class_of_dev(hdev, skb);
2129 break;
2130
2131 case HCI_OP_WRITE_CLASS_OF_DEV:
2132 hci_cc_write_class_of_dev(hdev, skb);
2133 break;
2134
2135 case HCI_OP_READ_VOICE_SETTING:
2136 hci_cc_read_voice_setting(hdev, skb);
2137 break;
2138
2139 case HCI_OP_WRITE_VOICE_SETTING:
2140 hci_cc_write_voice_setting(hdev, skb);
2141 break;
2142
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002143 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2144 hci_cc_read_num_supported_iac(hdev, skb);
2145 break;
2146
Marcel Holtmann333140b2008-07-14 20:13:48 +02002147 case HCI_OP_WRITE_SSP_MODE:
2148 hci_cc_write_ssp_mode(hdev, skb);
2149 break;
2150
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002151 case HCI_OP_READ_LOCAL_VERSION:
2152 hci_cc_read_local_version(hdev, skb);
2153 break;
2154
2155 case HCI_OP_READ_LOCAL_COMMANDS:
2156 hci_cc_read_local_commands(hdev, skb);
2157 break;
2158
2159 case HCI_OP_READ_LOCAL_FEATURES:
2160 hci_cc_read_local_features(hdev, skb);
2161 break;
2162
Andre Guedes971e3a42011-06-30 19:20:52 -03002163 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2164 hci_cc_read_local_ext_features(hdev, skb);
2165 break;
2166
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002167 case HCI_OP_READ_BUFFER_SIZE:
2168 hci_cc_read_buffer_size(hdev, skb);
2169 break;
2170
2171 case HCI_OP_READ_BD_ADDR:
2172 hci_cc_read_bd_addr(hdev, skb);
2173 break;
2174
Johan Hedbergf332ec62013-03-15 17:07:11 -05002175 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2176 hci_cc_read_page_scan_activity(hdev, skb);
2177 break;
2178
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002179 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2180 hci_cc_write_page_scan_activity(hdev, skb);
2181 break;
2182
Johan Hedbergf332ec62013-03-15 17:07:11 -05002183 case HCI_OP_READ_PAGE_SCAN_TYPE:
2184 hci_cc_read_page_scan_type(hdev, skb);
2185 break;
2186
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002187 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2188 hci_cc_write_page_scan_type(hdev, skb);
2189 break;
2190
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002191 case HCI_OP_READ_DATA_BLOCK_SIZE:
2192 hci_cc_read_data_block_size(hdev, skb);
2193 break;
2194
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002195 case HCI_OP_READ_FLOW_CONTROL_MODE:
2196 hci_cc_read_flow_control_mode(hdev, skb);
2197 break;
2198
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002199 case HCI_OP_READ_LOCAL_AMP_INFO:
2200 hci_cc_read_local_amp_info(hdev, skb);
2201 break;
2202
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002203 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2204 hci_cc_read_local_amp_assoc(hdev, skb);
2205 break;
2206
Johan Hedbergd5859e22011-01-25 01:19:58 +02002207 case HCI_OP_READ_INQ_RSP_TX_POWER:
2208 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2209 break;
2210
Johan Hedberg980e1a52011-01-22 06:10:07 +02002211 case HCI_OP_PIN_CODE_REPLY:
2212 hci_cc_pin_code_reply(hdev, skb);
2213 break;
2214
2215 case HCI_OP_PIN_CODE_NEG_REPLY:
2216 hci_cc_pin_code_neg_reply(hdev, skb);
2217 break;
2218
Szymon Jancc35938b2011-03-22 13:12:21 +01002219 case HCI_OP_READ_LOCAL_OOB_DATA:
2220 hci_cc_read_local_oob_data_reply(hdev, skb);
2221 break;
2222
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002223 case HCI_OP_LE_READ_BUFFER_SIZE:
2224 hci_cc_le_read_buffer_size(hdev, skb);
2225 break;
2226
Johan Hedberg60e77322013-01-22 14:01:59 +02002227 case HCI_OP_LE_READ_LOCAL_FEATURES:
2228 hci_cc_le_read_local_features(hdev, skb);
2229 break;
2230
Johan Hedberg8fa19092012-10-19 20:57:49 +03002231 case HCI_OP_LE_READ_ADV_TX_POWER:
2232 hci_cc_le_read_adv_tx_power(hdev, skb);
2233 break;
2234
Johan Hedberga5c29682011-02-19 12:05:57 -03002235 case HCI_OP_USER_CONFIRM_REPLY:
2236 hci_cc_user_confirm_reply(hdev, skb);
2237 break;
2238
2239 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2240 hci_cc_user_confirm_neg_reply(hdev, skb);
2241 break;
2242
Brian Gix1143d452011-11-23 08:28:34 -08002243 case HCI_OP_USER_PASSKEY_REPLY:
2244 hci_cc_user_passkey_reply(hdev, skb);
2245 break;
2246
2247 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2248 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002249 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002250
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002251 case HCI_OP_LE_SET_ADV_ENABLE:
2252 hci_cc_le_set_adv_enable(hdev, skb);
2253 break;
2254
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002255 case HCI_OP_LE_SET_SCAN_ENABLE:
2256 hci_cc_le_set_scan_enable(hdev, skb);
2257 break;
2258
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002259 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2260 hci_cc_le_read_white_list_size(hdev, skb);
2261 break;
2262
Johan Hedberg9b008c02013-01-22 14:02:01 +02002263 case HCI_OP_LE_READ_SUPPORTED_STATES:
2264 hci_cc_le_read_supported_states(hdev, skb);
2265 break;
2266
Andre Guedesf9b49302011-06-30 19:20:53 -03002267 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2268 hci_cc_write_le_host_supported(hdev, skb);
2269 break;
2270
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002271 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2272 hci_cc_write_remote_amp_assoc(hdev, skb);
2273 break;
2274
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002275 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002276 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002277 break;
2278 }
2279
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002280 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002281 del_timer(&hdev->cmd_timer);
2282
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002283 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002284
Szymon Jancdbccd792012-12-11 08:51:19 +01002285 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002286 atomic_set(&hdev->cmd_cnt, 1);
2287 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002288 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002289 }
2290}
2291
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002292static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002293{
2294 struct hci_ev_cmd_status *ev = (void *) skb->data;
2295 __u16 opcode;
2296
2297 skb_pull(skb, sizeof(*ev));
2298
2299 opcode = __le16_to_cpu(ev->opcode);
2300
2301 switch (opcode) {
2302 case HCI_OP_INQUIRY:
2303 hci_cs_inquiry(hdev, ev->status);
2304 break;
2305
2306 case HCI_OP_CREATE_CONN:
2307 hci_cs_create_conn(hdev, ev->status);
2308 break;
2309
2310 case HCI_OP_ADD_SCO:
2311 hci_cs_add_sco(hdev, ev->status);
2312 break;
2313
Marcel Holtmannf8558552008-07-14 20:13:49 +02002314 case HCI_OP_AUTH_REQUESTED:
2315 hci_cs_auth_requested(hdev, ev->status);
2316 break;
2317
2318 case HCI_OP_SET_CONN_ENCRYPT:
2319 hci_cs_set_conn_encrypt(hdev, ev->status);
2320 break;
2321
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002322 case HCI_OP_REMOTE_NAME_REQ:
2323 hci_cs_remote_name_req(hdev, ev->status);
2324 break;
2325
Marcel Holtmann769be972008-07-14 20:13:49 +02002326 case HCI_OP_READ_REMOTE_FEATURES:
2327 hci_cs_read_remote_features(hdev, ev->status);
2328 break;
2329
2330 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2331 hci_cs_read_remote_ext_features(hdev, ev->status);
2332 break;
2333
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002334 case HCI_OP_SETUP_SYNC_CONN:
2335 hci_cs_setup_sync_conn(hdev, ev->status);
2336 break;
2337
2338 case HCI_OP_SNIFF_MODE:
2339 hci_cs_sniff_mode(hdev, ev->status);
2340 break;
2341
2342 case HCI_OP_EXIT_SNIFF_MODE:
2343 hci_cs_exit_sniff_mode(hdev, ev->status);
2344 break;
2345
Johan Hedberg8962ee72011-01-20 12:40:27 +02002346 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002347 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002348 break;
2349
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002350 case HCI_OP_CREATE_PHY_LINK:
2351 hci_cs_create_phylink(hdev, ev->status);
2352 break;
2353
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002354 case HCI_OP_ACCEPT_PHY_LINK:
2355 hci_cs_accept_phylink(hdev, ev->status);
2356 break;
2357
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002358 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002359 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002360 break;
2361 }
2362
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002363 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002364 del_timer(&hdev->cmd_timer);
2365
Johan Hedberg02350a72013-04-03 21:50:29 +03002366 if (ev->status ||
2367 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2368 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002369
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002370 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002371 atomic_set(&hdev->cmd_cnt, 1);
2372 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002373 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002374 }
2375}
2376
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002377static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002378{
2379 struct hci_ev_role_change *ev = (void *) skb->data;
2380 struct hci_conn *conn;
2381
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002382 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002383
2384 hci_dev_lock(hdev);
2385
2386 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2387 if (conn) {
2388 if (!ev->status) {
2389 if (ev->role)
2390 conn->link_mode &= ~HCI_LM_MASTER;
2391 else
2392 conn->link_mode |= HCI_LM_MASTER;
2393 }
2394
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002395 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002396
2397 hci_role_switch_cfm(conn, ev->status, ev->role);
2398 }
2399
2400 hci_dev_unlock(hdev);
2401}
2402
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002403static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002404{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002405 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002406 int i;
2407
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002408 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2409 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2410 return;
2411 }
2412
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002413 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002414 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002415 BT_DBG("%s bad parameters", hdev->name);
2416 return;
2417 }
2418
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002419 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2420
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002421 for (i = 0; i < ev->num_hndl; i++) {
2422 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002423 struct hci_conn *conn;
2424 __u16 handle, count;
2425
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002426 handle = __le16_to_cpu(info->handle);
2427 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002428
2429 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002430 if (!conn)
2431 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002432
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002433 conn->sent -= count;
2434
2435 switch (conn->type) {
2436 case ACL_LINK:
2437 hdev->acl_cnt += count;
2438 if (hdev->acl_cnt > hdev->acl_pkts)
2439 hdev->acl_cnt = hdev->acl_pkts;
2440 break;
2441
2442 case LE_LINK:
2443 if (hdev->le_pkts) {
2444 hdev->le_cnt += count;
2445 if (hdev->le_cnt > hdev->le_pkts)
2446 hdev->le_cnt = hdev->le_pkts;
2447 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002448 hdev->acl_cnt += count;
2449 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002450 hdev->acl_cnt = hdev->acl_pkts;
2451 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002452 break;
2453
2454 case SCO_LINK:
2455 hdev->sco_cnt += count;
2456 if (hdev->sco_cnt > hdev->sco_pkts)
2457 hdev->sco_cnt = hdev->sco_pkts;
2458 break;
2459
2460 default:
2461 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2462 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002463 }
2464 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002465
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002466 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002467}
2468
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002469static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2470 __u16 handle)
2471{
2472 struct hci_chan *chan;
2473
2474 switch (hdev->dev_type) {
2475 case HCI_BREDR:
2476 return hci_conn_hash_lookup_handle(hdev, handle);
2477 case HCI_AMP:
2478 chan = hci_chan_lookup_handle(hdev, handle);
2479 if (chan)
2480 return chan->conn;
2481 break;
2482 default:
2483 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2484 break;
2485 }
2486
2487 return NULL;
2488}
2489
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002490static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002491{
2492 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2493 int i;
2494
2495 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2496 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2497 return;
2498 }
2499
2500 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002501 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002502 BT_DBG("%s bad parameters", hdev->name);
2503 return;
2504 }
2505
2506 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002507 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002508
2509 for (i = 0; i < ev->num_hndl; i++) {
2510 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002511 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002512 __u16 handle, block_count;
2513
2514 handle = __le16_to_cpu(info->handle);
2515 block_count = __le16_to_cpu(info->blocks);
2516
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002517 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002518 if (!conn)
2519 continue;
2520
2521 conn->sent -= block_count;
2522
2523 switch (conn->type) {
2524 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002525 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002526 hdev->block_cnt += block_count;
2527 if (hdev->block_cnt > hdev->num_blocks)
2528 hdev->block_cnt = hdev->num_blocks;
2529 break;
2530
2531 default:
2532 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2533 break;
2534 }
2535 }
2536
2537 queue_work(hdev->workqueue, &hdev->tx_work);
2538}
2539
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002540static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002542 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002543 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002545 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002546
2547 hci_dev_lock(hdev);
2548
Marcel Holtmann04837f62006-07-03 10:02:33 +02002549 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2550 if (conn) {
2551 conn->mode = ev->mode;
2552 conn->interval = __le16_to_cpu(ev->interval);
2553
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002554 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2555 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002556 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002557 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002558 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002559 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002560 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002561
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002562 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002563 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002564 }
2565
2566 hci_dev_unlock(hdev);
2567}
2568
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002569static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002571 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2572 struct hci_conn *conn;
2573
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002574 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002575
2576 hci_dev_lock(hdev);
2577
2578 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002579 if (!conn)
2580 goto unlock;
2581
2582 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002583 hci_conn_hold(conn);
2584 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002585 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002586 }
2587
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002588 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002589 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002590 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002591 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002592 u8 secure;
2593
2594 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2595 secure = 1;
2596 else
2597 secure = 0;
2598
Johan Hedberg744cf192011-11-08 20:40:14 +02002599 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002600 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002601
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002602unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002603 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604}
2605
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002606static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002607{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002608 struct hci_ev_link_key_req *ev = (void *) skb->data;
2609 struct hci_cp_link_key_reply cp;
2610 struct hci_conn *conn;
2611 struct link_key *key;
2612
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002613 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002614
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002615 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002616 return;
2617
2618 hci_dev_lock(hdev);
2619
2620 key = hci_find_link_key(hdev, &ev->bdaddr);
2621 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002622 BT_DBG("%s link key not found for %pMR", hdev->name,
2623 &ev->bdaddr);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002624 goto not_found;
2625 }
2626
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002627 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2628 &ev->bdaddr);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002629
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002630 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002631 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002632 BT_DBG("%s ignoring debug key", hdev->name);
2633 goto not_found;
2634 }
2635
2636 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002637 if (conn) {
2638 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002639 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002640 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2641 goto not_found;
2642 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002643
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002644 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002645 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002646 BT_DBG("%s ignoring key unauthenticated for high security",
2647 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002648 goto not_found;
2649 }
2650
2651 conn->key_type = key->type;
2652 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002653 }
2654
2655 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002656 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002657
2658 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2659
2660 hci_dev_unlock(hdev);
2661
2662 return;
2663
2664not_found:
2665 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2666 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667}
2668
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002669static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002670{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002671 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2672 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002673 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002674
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002675 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002676
2677 hci_dev_lock(hdev);
2678
2679 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2680 if (conn) {
2681 hci_conn_hold(conn);
2682 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002683 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002684
2685 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2686 conn->key_type = ev->key_type;
2687
David Herrmann76a68ba2013-04-06 20:28:37 +02002688 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002689 }
2690
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002691 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002692 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002693 ev->key_type, pin_len);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002694
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002695 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696}
2697
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002698static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002699{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002700 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002701 struct hci_conn *conn;
2702
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002703 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002704
2705 hci_dev_lock(hdev);
2706
2707 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002708 if (conn && !ev->status) {
2709 struct inquiry_entry *ie;
2710
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002711 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2712 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002713 ie->data.clock_offset = ev->clock_offset;
2714 ie->timestamp = jiffies;
2715 }
2716 }
2717
2718 hci_dev_unlock(hdev);
2719}
2720
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002721static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002722{
2723 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2724 struct hci_conn *conn;
2725
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002726 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002727
2728 hci_dev_lock(hdev);
2729
2730 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2731 if (conn && !ev->status)
2732 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2733
2734 hci_dev_unlock(hdev);
2735}
2736
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002737static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002738{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002739 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002740 struct inquiry_entry *ie;
2741
2742 BT_DBG("%s", hdev->name);
2743
2744 hci_dev_lock(hdev);
2745
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002746 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2747 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002748 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2749 ie->timestamp = jiffies;
2750 }
2751
2752 hci_dev_unlock(hdev);
2753}
2754
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002755static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2756 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002757{
2758 struct inquiry_data data;
2759 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002760 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002761
2762 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2763
2764 if (!num_rsp)
2765 return;
2766
Andre Guedes1519cc12012-03-21 00:03:38 -03002767 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2768 return;
2769
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002770 hci_dev_lock(hdev);
2771
2772 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002773 struct inquiry_info_with_rssi_and_pscan_mode *info;
2774 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002775
Johan Hedberge17acd42011-03-30 23:57:16 +03002776 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002777 bacpy(&data.bdaddr, &info->bdaddr);
2778 data.pscan_rep_mode = info->pscan_rep_mode;
2779 data.pscan_period_mode = info->pscan_period_mode;
2780 data.pscan_mode = info->pscan_mode;
2781 memcpy(data.dev_class, info->dev_class, 3);
2782 data.clock_offset = info->clock_offset;
2783 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002784 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002785
2786 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002787 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002788 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002789 info->dev_class, info->rssi,
2790 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002791 }
2792 } else {
2793 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2794
Johan Hedberge17acd42011-03-30 23:57:16 +03002795 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002796 bacpy(&data.bdaddr, &info->bdaddr);
2797 data.pscan_rep_mode = info->pscan_rep_mode;
2798 data.pscan_period_mode = info->pscan_period_mode;
2799 data.pscan_mode = 0x00;
2800 memcpy(data.dev_class, info->dev_class, 3);
2801 data.clock_offset = info->clock_offset;
2802 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002803 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002804 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002805 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002806 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002807 info->dev_class, info->rssi,
2808 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002809 }
2810 }
2811
2812 hci_dev_unlock(hdev);
2813}
2814
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002815static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2816 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002817{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002818 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2819 struct hci_conn *conn;
2820
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002821 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002822
Marcel Holtmann41a96212008-07-14 20:13:48 +02002823 hci_dev_lock(hdev);
2824
2825 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002826 if (!conn)
2827 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002828
Johan Hedbergcad718e2013-04-17 15:00:51 +03002829 if (ev->page < HCI_MAX_PAGES)
2830 memcpy(conn->features[ev->page], ev->features, 8);
2831
Johan Hedbergccd556f2010-11-10 17:11:51 +02002832 if (!ev->status && ev->page == 0x01) {
2833 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002834
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002835 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2836 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002837 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002838
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302839 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002840 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302841 } else {
2842 /* It is mandatory by the Bluetooth specification that
2843 * Extended Inquiry Results are only used when Secure
2844 * Simple Pairing is enabled, but some devices violate
2845 * this.
2846 *
2847 * To make these devices work, the internal SSP
2848 * enabled flag needs to be cleared if the remote host
2849 * features do not indicate SSP support */
2850 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2851 }
Marcel Holtmann41a96212008-07-14 20:13:48 +02002852 }
2853
Johan Hedbergccd556f2010-11-10 17:11:51 +02002854 if (conn->state != BT_CONFIG)
2855 goto unlock;
2856
Johan Hedberg671267b2012-05-12 16:11:50 -03002857 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002858 struct hci_cp_remote_name_req cp;
2859 memset(&cp, 0, sizeof(cp));
2860 bacpy(&cp.bdaddr, &conn->dst);
2861 cp.pscan_rep_mode = 0x02;
2862 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002863 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2864 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002865 conn->dst_type, 0, NULL, 0,
2866 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002867
Johan Hedberg127178d2010-11-18 22:22:29 +02002868 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002869 conn->state = BT_CONNECTED;
2870 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002871 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002872 }
2873
2874unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002875 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002876}
2877
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002878static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2879 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002880{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002881 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2882 struct hci_conn *conn;
2883
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002884 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002885
2886 hci_dev_lock(hdev);
2887
2888 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002889 if (!conn) {
2890 if (ev->link_type == ESCO_LINK)
2891 goto unlock;
2892
2893 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2894 if (!conn)
2895 goto unlock;
2896
2897 conn->type = SCO_LINK;
2898 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002899
Marcel Holtmann732547f2009-04-19 19:14:14 +02002900 switch (ev->status) {
2901 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002902 conn->handle = __le16_to_cpu(ev->handle);
2903 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002904
2905 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002906 break;
2907
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02002908 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05002909 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002910 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002911 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002912 case 0x1f: /* Unspecified error */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002913 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02002914 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2915 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002916 if (hci_setup_sync(conn, conn->link->handle))
2917 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002918 }
2919 /* fall through */
2920
2921 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002922 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002923 break;
2924 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002925
2926 hci_proto_connect_cfm(conn, ev->status);
2927 if (ev->status)
2928 hci_conn_del(conn);
2929
2930unlock:
2931 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002932}
2933
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07002934static inline size_t eir_get_length(u8 *eir, size_t eir_len)
2935{
2936 size_t parsed = 0;
2937
2938 while (parsed < eir_len) {
2939 u8 field_len = eir[0];
2940
2941 if (field_len == 0)
2942 return parsed;
2943
2944 parsed += field_len + 1;
2945 eir += field_len + 1;
2946 }
2947
2948 return eir_len;
2949}
2950
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002951static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
2952 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002953{
2954 struct inquiry_data data;
2955 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2956 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302957 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002958
2959 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2960
2961 if (!num_rsp)
2962 return;
2963
Andre Guedes1519cc12012-03-21 00:03:38 -03002964 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2965 return;
2966
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002967 hci_dev_lock(hdev);
2968
Johan Hedberge17acd42011-03-30 23:57:16 +03002969 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002970 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002971
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002972 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002973 data.pscan_rep_mode = info->pscan_rep_mode;
2974 data.pscan_period_mode = info->pscan_period_mode;
2975 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002976 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002977 data.clock_offset = info->clock_offset;
2978 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002979 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002980
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002981 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002982 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002983 sizeof(info->data),
2984 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002985 else
2986 name_known = true;
2987
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002988 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002989 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302990 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02002991 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002992 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302993 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002994 }
2995
2996 hci_dev_unlock(hdev);
2997}
2998
Johan Hedberg1c2e0042012-06-08 23:31:13 +08002999static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3000 struct sk_buff *skb)
3001{
3002 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3003 struct hci_conn *conn;
3004
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003005 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003006 __le16_to_cpu(ev->handle));
3007
3008 hci_dev_lock(hdev);
3009
3010 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3011 if (!conn)
3012 goto unlock;
3013
3014 if (!ev->status)
3015 conn->sec_level = conn->pending_sec_level;
3016
3017 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3018
3019 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003020 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003021 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003022 goto unlock;
3023 }
3024
3025 if (conn->state == BT_CONFIG) {
3026 if (!ev->status)
3027 conn->state = BT_CONNECTED;
3028
3029 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003030 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003031 } else {
3032 hci_auth_cfm(conn, ev->status);
3033
3034 hci_conn_hold(conn);
3035 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003036 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003037 }
3038
3039unlock:
3040 hci_dev_unlock(hdev);
3041}
3042
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003043static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003044{
3045 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003046 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3047 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003048 /* If both remote and local IO capabilities allow MITM
3049 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003050 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3051 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3052 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003053 else
Mikel Astizacabae92013-06-28 10:56:28 +02003054 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003055 }
3056
3057 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003058 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3059 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003060 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003061
3062 return conn->auth_type;
3063}
3064
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003065static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003066{
3067 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3068 struct hci_conn *conn;
3069
3070 BT_DBG("%s", hdev->name);
3071
3072 hci_dev_lock(hdev);
3073
3074 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003075 if (!conn)
3076 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003077
Johan Hedberg03b555e2011-01-04 15:40:05 +02003078 hci_conn_hold(conn);
3079
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003080 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003081 goto unlock;
3082
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003083 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003084 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003085 struct hci_cp_io_capability_reply cp;
3086
3087 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303088 /* Change the IO capability from KeyboardDisplay
3089 * to DisplayYesNo as it is not supported by BT spec. */
3090 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003091 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003092 conn->auth_type = hci_get_auth_req(conn);
3093 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003094
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003095 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3096 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003097 cp.oob_data = 0x01;
3098 else
3099 cp.oob_data = 0x00;
3100
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003101 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003102 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003103 } else {
3104 struct hci_cp_io_capability_neg_reply cp;
3105
3106 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003107 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003108
3109 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003110 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003111 }
3112
3113unlock:
3114 hci_dev_unlock(hdev);
3115}
3116
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003117static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003118{
3119 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3120 struct hci_conn *conn;
3121
3122 BT_DBG("%s", hdev->name);
3123
3124 hci_dev_lock(hdev);
3125
3126 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3127 if (!conn)
3128 goto unlock;
3129
Johan Hedberg03b555e2011-01-04 15:40:05 +02003130 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003131 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003132 if (ev->oob_data)
3133 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003134
3135unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003136 hci_dev_unlock(hdev);
3137}
3138
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003139static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3140 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003141{
3142 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003143 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003144 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003145
3146 BT_DBG("%s", hdev->name);
3147
3148 hci_dev_lock(hdev);
3149
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003150 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003151 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003152
Johan Hedberg7a828902011-04-28 11:28:53 -07003153 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3154 if (!conn)
3155 goto unlock;
3156
3157 loc_mitm = (conn->auth_type & 0x01);
3158 rem_mitm = (conn->remote_auth & 0x01);
3159
3160 /* If we require MITM but the remote device can't provide that
3161 * (it has NoInputNoOutput) then reject the confirmation
3162 * request. The only exception is when we're dedicated bonding
3163 * initiators (connect_cfm_cb set) since then we always have the MITM
3164 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003165 if (!conn->connect_cfm_cb && loc_mitm &&
3166 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003167 BT_DBG("Rejecting request: remote device can't provide MITM");
3168 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003169 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003170 goto unlock;
3171 }
3172
3173 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003174 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3175 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003176
3177 /* If we're not the initiators request authorization to
3178 * proceed from user space (mgmt_user_confirm with
3179 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003180 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003181 BT_DBG("Confirming auto-accept as acceptor");
3182 confirm_hint = 1;
3183 goto confirm;
3184 }
3185
Johan Hedberg9f616562011-04-28 11:28:54 -07003186 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003187 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003188
3189 if (hdev->auto_accept_delay > 0) {
3190 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3191 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3192 goto unlock;
3193 }
3194
Johan Hedberg7a828902011-04-28 11:28:53 -07003195 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003196 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003197 goto unlock;
3198 }
3199
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003200confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003201 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003202 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003203
3204unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003205 hci_dev_unlock(hdev);
3206}
3207
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003208static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3209 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003210{
3211 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3212
3213 BT_DBG("%s", hdev->name);
3214
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003215 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003216 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003217}
3218
Johan Hedberg92a25252012-09-06 18:39:26 +03003219static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3220 struct sk_buff *skb)
3221{
3222 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3223 struct hci_conn *conn;
3224
3225 BT_DBG("%s", hdev->name);
3226
3227 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3228 if (!conn)
3229 return;
3230
3231 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3232 conn->passkey_entered = 0;
3233
3234 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3235 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3236 conn->dst_type, conn->passkey_notify,
3237 conn->passkey_entered);
3238}
3239
3240static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3241{
3242 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3243 struct hci_conn *conn;
3244
3245 BT_DBG("%s", hdev->name);
3246
3247 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3248 if (!conn)
3249 return;
3250
3251 switch (ev->type) {
3252 case HCI_KEYPRESS_STARTED:
3253 conn->passkey_entered = 0;
3254 return;
3255
3256 case HCI_KEYPRESS_ENTERED:
3257 conn->passkey_entered++;
3258 break;
3259
3260 case HCI_KEYPRESS_ERASED:
3261 conn->passkey_entered--;
3262 break;
3263
3264 case HCI_KEYPRESS_CLEARED:
3265 conn->passkey_entered = 0;
3266 break;
3267
3268 case HCI_KEYPRESS_COMPLETED:
3269 return;
3270 }
3271
3272 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3273 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3274 conn->dst_type, conn->passkey_notify,
3275 conn->passkey_entered);
3276}
3277
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003278static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3279 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003280{
3281 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3282 struct hci_conn *conn;
3283
3284 BT_DBG("%s", hdev->name);
3285
3286 hci_dev_lock(hdev);
3287
3288 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003289 if (!conn)
3290 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003291
Johan Hedberg2a611692011-02-19 12:06:00 -03003292 /* To avoid duplicate auth_failed events to user space we check
3293 * the HCI_CONN_AUTH_PEND flag which will be set if we
3294 * initiated the authentication. A traditional auth_complete
3295 * event gets always produced as initiator and is also mapped to
3296 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003297 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003298 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003299 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003300
David Herrmann76a68ba2013-04-06 20:28:37 +02003301 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003302
3303unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003304 hci_dev_unlock(hdev);
3305}
3306
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003307static void hci_remote_host_features_evt(struct hci_dev *hdev,
3308 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003309{
3310 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3311 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003312 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003313
3314 BT_DBG("%s", hdev->name);
3315
3316 hci_dev_lock(hdev);
3317
Johan Hedbergcad718e2013-04-17 15:00:51 +03003318 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3319 if (conn)
3320 memcpy(conn->features[1], ev->features, 8);
3321
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003322 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3323 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003324 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003325
3326 hci_dev_unlock(hdev);
3327}
3328
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003329static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3330 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003331{
3332 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3333 struct oob_data *data;
3334
3335 BT_DBG("%s", hdev->name);
3336
3337 hci_dev_lock(hdev);
3338
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003339 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003340 goto unlock;
3341
Szymon Janc2763eda2011-03-22 13:12:22 +01003342 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3343 if (data) {
3344 struct hci_cp_remote_oob_data_reply cp;
3345
3346 bacpy(&cp.bdaddr, &ev->bdaddr);
3347 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3348 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3349
3350 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003351 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003352 } else {
3353 struct hci_cp_remote_oob_data_neg_reply cp;
3354
3355 bacpy(&cp.bdaddr, &ev->bdaddr);
3356 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003357 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003358 }
3359
Szymon Jance1ba1f12011-04-06 13:01:59 +02003360unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003361 hci_dev_unlock(hdev);
3362}
3363
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003364static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3365 struct sk_buff *skb)
3366{
3367 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3368 struct hci_conn *hcon, *bredr_hcon;
3369
3370 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3371 ev->status);
3372
3373 hci_dev_lock(hdev);
3374
3375 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3376 if (!hcon) {
3377 hci_dev_unlock(hdev);
3378 return;
3379 }
3380
3381 if (ev->status) {
3382 hci_conn_del(hcon);
3383 hci_dev_unlock(hdev);
3384 return;
3385 }
3386
3387 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3388
3389 hcon->state = BT_CONNECTED;
3390 bacpy(&hcon->dst, &bredr_hcon->dst);
3391
3392 hci_conn_hold(hcon);
3393 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003394 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003395
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003396 hci_conn_add_sysfs(hcon);
3397
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003398 amp_physical_cfm(bredr_hcon, hcon);
3399
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003400 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003401}
3402
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003403static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3404{
3405 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3406 struct hci_conn *hcon;
3407 struct hci_chan *hchan;
3408 struct amp_mgr *mgr;
3409
3410 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3411 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3412 ev->status);
3413
3414 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3415 if (!hcon)
3416 return;
3417
3418 /* Create AMP hchan */
3419 hchan = hci_chan_create(hcon);
3420 if (!hchan)
3421 return;
3422
3423 hchan->handle = le16_to_cpu(ev->handle);
3424
3425 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3426
3427 mgr = hcon->amp_mgr;
3428 if (mgr && mgr->bredr_chan) {
3429 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3430
3431 l2cap_chan_lock(bredr_chan);
3432
3433 bredr_chan->conn->mtu = hdev->block_mtu;
3434 l2cap_logical_cfm(bredr_chan, hchan, 0);
3435 hci_conn_hold(hcon);
3436
3437 l2cap_chan_unlock(bredr_chan);
3438 }
3439}
3440
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003441static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3442 struct sk_buff *skb)
3443{
3444 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3445 struct hci_chan *hchan;
3446
3447 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3448 le16_to_cpu(ev->handle), ev->status);
3449
3450 if (ev->status)
3451 return;
3452
3453 hci_dev_lock(hdev);
3454
3455 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3456 if (!hchan)
3457 goto unlock;
3458
3459 amp_destroy_logical_link(hchan, ev->reason);
3460
3461unlock:
3462 hci_dev_unlock(hdev);
3463}
3464
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003465static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3466 struct sk_buff *skb)
3467{
3468 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3469 struct hci_conn *hcon;
3470
3471 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3472
3473 if (ev->status)
3474 return;
3475
3476 hci_dev_lock(hdev);
3477
3478 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3479 if (hcon) {
3480 hcon->state = BT_CLOSED;
3481 hci_conn_del(hcon);
3482 }
3483
3484 hci_dev_unlock(hdev);
3485}
3486
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003487static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003488{
3489 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3490 struct hci_conn *conn;
3491
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003492 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003493
3494 hci_dev_lock(hdev);
3495
Andre Guedesb47a09b2012-07-27 15:10:15 -03003496 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003497 if (!conn) {
3498 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3499 if (!conn) {
3500 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003501 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003502 }
Andre Guedes29b79882011-05-31 14:20:54 -03003503
3504 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003505
Marcel Holtmann880be4e2013-10-13 07:25:18 -07003506 /* The advertising parameters for own address type
3507 * define which source address and source address
3508 * type this connections has.
3509 */
3510 if (bacmp(&conn->src, BDADDR_ANY)) {
3511 conn->src_type = ADDR_LE_DEV_PUBLIC;
3512 } else {
3513 bacpy(&conn->src, &hdev->static_addr);
3514 conn->src_type = ADDR_LE_DEV_RANDOM;
3515 }
3516
Andre Guedesb9b343d2012-07-27 15:10:11 -03003517 if (ev->role == LE_CONN_ROLE_MASTER) {
3518 conn->out = true;
3519 conn->link_mode |= HCI_LM_MASTER;
3520 }
Ville Tervob62f3282011-02-10 22:38:50 -03003521 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003522
Andre Guedescd17dec2012-07-27 15:10:16 -03003523 if (ev->status) {
3524 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3525 conn->dst_type, ev->status);
3526 hci_proto_connect_cfm(conn, ev->status);
3527 conn->state = BT_CLOSED;
3528 hci_conn_del(conn);
3529 goto unlock;
3530 }
3531
Johan Hedbergb644ba32012-01-17 21:48:47 +02003532 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3533 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003534 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003535
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003536 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003537 conn->handle = __le16_to_cpu(ev->handle);
3538 conn->state = BT_CONNECTED;
3539
Ville Tervofcd89c02011-02-10 22:38:47 -03003540 hci_conn_add_sysfs(conn);
3541
3542 hci_proto_connect_cfm(conn, ev->status);
3543
3544unlock:
3545 hci_dev_unlock(hdev);
3546}
3547
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003548static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003549{
Andre Guedese95beb42011-09-26 20:48:35 -03003550 u8 num_reports = skb->data[0];
3551 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003552 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003553
Andre Guedese95beb42011-09-26 20:48:35 -03003554 while (num_reports--) {
3555 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003556
Andre Guedes3c9e9192012-01-10 18:20:50 -03003557 rssi = ev->data[ev->length];
3558 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003559 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003560
Andre Guedese95beb42011-09-26 20:48:35 -03003561 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003562 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003563}
3564
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003565static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003566{
3567 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3568 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003569 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003570 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003571 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003572
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003573 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003574
3575 hci_dev_lock(hdev);
3576
3577 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003578 if (conn == NULL)
3579 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003580
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003581 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3582 if (ltk == NULL)
3583 goto not_found;
3584
3585 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003586 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003587
3588 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03003589 conn->pending_sec_level = BT_SECURITY_HIGH;
3590 else
3591 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003592
Andre Guedes89cbb4d2013-07-31 16:25:29 -03003593 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003594
3595 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3596
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003597 if (ltk->type & HCI_SMP_STK) {
3598 list_del(&ltk->list);
3599 kfree(ltk);
3600 }
3601
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003602 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003603
3604 return;
3605
3606not_found:
3607 neg.handle = ev->handle;
3608 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3609 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003610}
3611
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003612static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003613{
3614 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3615
3616 skb_pull(skb, sizeof(*le_ev));
3617
3618 switch (le_ev->subevent) {
3619 case HCI_EV_LE_CONN_COMPLETE:
3620 hci_le_conn_complete_evt(hdev, skb);
3621 break;
3622
Andre Guedes9aa04c92011-05-26 16:23:51 -03003623 case HCI_EV_LE_ADVERTISING_REPORT:
3624 hci_le_adv_report_evt(hdev, skb);
3625 break;
3626
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003627 case HCI_EV_LE_LTK_REQ:
3628 hci_le_ltk_request_evt(hdev, skb);
3629 break;
3630
Ville Tervofcd89c02011-02-10 22:38:47 -03003631 default:
3632 break;
3633 }
3634}
3635
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003636static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3637{
3638 struct hci_ev_channel_selected *ev = (void *) skb->data;
3639 struct hci_conn *hcon;
3640
3641 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3642
3643 skb_pull(skb, sizeof(*ev));
3644
3645 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3646 if (!hcon)
3647 return;
3648
3649 amp_read_loc_assoc_final_data(hdev, hcon);
3650}
3651
Linus Torvalds1da177e2005-04-16 15:20:36 -07003652void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3653{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003654 struct hci_event_hdr *hdr = (void *) skb->data;
3655 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003656
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003657 hci_dev_lock(hdev);
3658
3659 /* Received events are (currently) only needed when a request is
3660 * ongoing so avoid unnecessary memory allocation.
3661 */
3662 if (hdev->req_status == HCI_REQ_PEND) {
3663 kfree_skb(hdev->recv_evt);
3664 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3665 }
3666
3667 hci_dev_unlock(hdev);
3668
Linus Torvalds1da177e2005-04-16 15:20:36 -07003669 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3670
Johan Hedberg02350a72013-04-03 21:50:29 +03003671 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02003672 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
3673 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03003674
3675 hci_req_cmd_complete(hdev, opcode, 0);
3676 }
3677
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003678 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003679 case HCI_EV_INQUIRY_COMPLETE:
3680 hci_inquiry_complete_evt(hdev, skb);
3681 break;
3682
3683 case HCI_EV_INQUIRY_RESULT:
3684 hci_inquiry_result_evt(hdev, skb);
3685 break;
3686
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003687 case HCI_EV_CONN_COMPLETE:
3688 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003689 break;
3690
Linus Torvalds1da177e2005-04-16 15:20:36 -07003691 case HCI_EV_CONN_REQUEST:
3692 hci_conn_request_evt(hdev, skb);
3693 break;
3694
Linus Torvalds1da177e2005-04-16 15:20:36 -07003695 case HCI_EV_DISCONN_COMPLETE:
3696 hci_disconn_complete_evt(hdev, skb);
3697 break;
3698
Linus Torvalds1da177e2005-04-16 15:20:36 -07003699 case HCI_EV_AUTH_COMPLETE:
3700 hci_auth_complete_evt(hdev, skb);
3701 break;
3702
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003703 case HCI_EV_REMOTE_NAME:
3704 hci_remote_name_evt(hdev, skb);
3705 break;
3706
Linus Torvalds1da177e2005-04-16 15:20:36 -07003707 case HCI_EV_ENCRYPT_CHANGE:
3708 hci_encrypt_change_evt(hdev, skb);
3709 break;
3710
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003711 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3712 hci_change_link_key_complete_evt(hdev, skb);
3713 break;
3714
3715 case HCI_EV_REMOTE_FEATURES:
3716 hci_remote_features_evt(hdev, skb);
3717 break;
3718
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003719 case HCI_EV_CMD_COMPLETE:
3720 hci_cmd_complete_evt(hdev, skb);
3721 break;
3722
3723 case HCI_EV_CMD_STATUS:
3724 hci_cmd_status_evt(hdev, skb);
3725 break;
3726
3727 case HCI_EV_ROLE_CHANGE:
3728 hci_role_change_evt(hdev, skb);
3729 break;
3730
3731 case HCI_EV_NUM_COMP_PKTS:
3732 hci_num_comp_pkts_evt(hdev, skb);
3733 break;
3734
3735 case HCI_EV_MODE_CHANGE:
3736 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003737 break;
3738
3739 case HCI_EV_PIN_CODE_REQ:
3740 hci_pin_code_request_evt(hdev, skb);
3741 break;
3742
3743 case HCI_EV_LINK_KEY_REQ:
3744 hci_link_key_request_evt(hdev, skb);
3745 break;
3746
3747 case HCI_EV_LINK_KEY_NOTIFY:
3748 hci_link_key_notify_evt(hdev, skb);
3749 break;
3750
3751 case HCI_EV_CLOCK_OFFSET:
3752 hci_clock_offset_evt(hdev, skb);
3753 break;
3754
Marcel Holtmanna8746412008-07-14 20:13:46 +02003755 case HCI_EV_PKT_TYPE_CHANGE:
3756 hci_pkt_type_change_evt(hdev, skb);
3757 break;
3758
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003759 case HCI_EV_PSCAN_REP_MODE:
3760 hci_pscan_rep_mode_evt(hdev, skb);
3761 break;
3762
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003763 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3764 hci_inquiry_result_with_rssi_evt(hdev, skb);
3765 break;
3766
3767 case HCI_EV_REMOTE_EXT_FEATURES:
3768 hci_remote_ext_features_evt(hdev, skb);
3769 break;
3770
3771 case HCI_EV_SYNC_CONN_COMPLETE:
3772 hci_sync_conn_complete_evt(hdev, skb);
3773 break;
3774
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003775 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3776 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003777 break;
3778
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003779 case HCI_EV_KEY_REFRESH_COMPLETE:
3780 hci_key_refresh_complete_evt(hdev, skb);
3781 break;
3782
Marcel Holtmann04936842008-07-14 20:13:48 +02003783 case HCI_EV_IO_CAPA_REQUEST:
3784 hci_io_capa_request_evt(hdev, skb);
3785 break;
3786
Johan Hedberg03b555e2011-01-04 15:40:05 +02003787 case HCI_EV_IO_CAPA_REPLY:
3788 hci_io_capa_reply_evt(hdev, skb);
3789 break;
3790
Johan Hedberga5c29682011-02-19 12:05:57 -03003791 case HCI_EV_USER_CONFIRM_REQUEST:
3792 hci_user_confirm_request_evt(hdev, skb);
3793 break;
3794
Brian Gix1143d452011-11-23 08:28:34 -08003795 case HCI_EV_USER_PASSKEY_REQUEST:
3796 hci_user_passkey_request_evt(hdev, skb);
3797 break;
3798
Johan Hedberg92a25252012-09-06 18:39:26 +03003799 case HCI_EV_USER_PASSKEY_NOTIFY:
3800 hci_user_passkey_notify_evt(hdev, skb);
3801 break;
3802
3803 case HCI_EV_KEYPRESS_NOTIFY:
3804 hci_keypress_notify_evt(hdev, skb);
3805 break;
3806
Marcel Holtmann04936842008-07-14 20:13:48 +02003807 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3808 hci_simple_pair_complete_evt(hdev, skb);
3809 break;
3810
Marcel Holtmann41a96212008-07-14 20:13:48 +02003811 case HCI_EV_REMOTE_HOST_FEATURES:
3812 hci_remote_host_features_evt(hdev, skb);
3813 break;
3814
Ville Tervofcd89c02011-02-10 22:38:47 -03003815 case HCI_EV_LE_META:
3816 hci_le_meta_evt(hdev, skb);
3817 break;
3818
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003819 case HCI_EV_CHANNEL_SELECTED:
3820 hci_chan_selected_evt(hdev, skb);
3821 break;
3822
Szymon Janc2763eda2011-03-22 13:12:22 +01003823 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3824 hci_remote_oob_data_request_evt(hdev, skb);
3825 break;
3826
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003827 case HCI_EV_PHY_LINK_COMPLETE:
3828 hci_phy_link_complete_evt(hdev, skb);
3829 break;
3830
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003831 case HCI_EV_LOGICAL_LINK_COMPLETE:
3832 hci_loglink_complete_evt(hdev, skb);
3833 break;
3834
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003835 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3836 hci_disconn_loglink_complete_evt(hdev, skb);
3837 break;
3838
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003839 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3840 hci_disconn_phylink_complete_evt(hdev, skb);
3841 break;
3842
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003843 case HCI_EV_NUM_COMP_BLOCKS:
3844 hci_num_comp_blocks_evt(hdev, skb);
3845 break;
3846
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003847 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003848 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003849 break;
3850 }
3851
3852 kfree_skb(skb);
3853 hdev->stat.evt_rx++;
3854}