blob: c171c0798499e02be9b58e36f105e01f2d19503a [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
Marcel Holtmann57af75a2013-10-18 12:04:47 -0700558 if (hdev->max_page < rp->max_page)
559 hdev->max_page = rp->max_page;
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300560
Johan Hedbergcad718e2013-04-17 15:00:51 +0300561 if (rp->page < HCI_MAX_PAGES)
562 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300563}
564
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200565static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300566 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200567{
568 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
569
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300570 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200571
Johan Hedberg42c6b122013-03-05 20:37:49 +0200572 if (!rp->status)
573 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200574}
575
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200576static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
577{
578 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
579
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300580 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200581
582 if (rp->status)
583 return;
584
585 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
586 hdev->sco_mtu = rp->sco_mtu;
587 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
588 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
589
590 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
591 hdev->sco_mtu = 64;
592 hdev->sco_pkts = 8;
593 }
594
595 hdev->acl_cnt = hdev->acl_pkts;
596 hdev->sco_cnt = hdev->sco_pkts;
597
Gustavo Padovan807deac2012-05-17 00:36:24 -0300598 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
599 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200600}
601
602static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
603{
604 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
605
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300606 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200607
608 if (!rp->status)
609 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200610}
611
Johan Hedbergf332ec62013-03-15 17:07:11 -0500612static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
613 struct sk_buff *skb)
614{
615 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
616
617 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
618
619 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
620 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
621 hdev->page_scan_window = __le16_to_cpu(rp->window);
622 }
623}
624
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500625static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
626 struct sk_buff *skb)
627{
628 u8 status = *((u8 *) skb->data);
629 struct hci_cp_write_page_scan_activity *sent;
630
631 BT_DBG("%s status 0x%2.2x", hdev->name, status);
632
633 if (status)
634 return;
635
636 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
637 if (!sent)
638 return;
639
640 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
641 hdev->page_scan_window = __le16_to_cpu(sent->window);
642}
643
Johan Hedbergf332ec62013-03-15 17:07:11 -0500644static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
645 struct sk_buff *skb)
646{
647 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
648
649 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
650
651 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
652 hdev->page_scan_type = rp->type;
653}
654
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500655static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
656 struct sk_buff *skb)
657{
658 u8 status = *((u8 *) skb->data);
659 u8 *type;
660
661 BT_DBG("%s status 0x%2.2x", hdev->name, status);
662
663 if (status)
664 return;
665
666 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
667 if (type)
668 hdev->page_scan_type = *type;
669}
670
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200671static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300672 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200673{
674 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
675
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300676 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200677
678 if (rp->status)
679 return;
680
681 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
682 hdev->block_len = __le16_to_cpu(rp->block_len);
683 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
684
685 hdev->block_cnt = hdev->num_blocks;
686
687 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300688 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200689}
690
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300691static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300692 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300693{
694 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
695
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300696 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300697
698 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300699 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300700
701 hdev->amp_status = rp->amp_status;
702 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
703 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
704 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
705 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
706 hdev->amp_type = rp->amp_type;
707 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
708 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
709 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
710 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
711
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300712a2mp_rsp:
713 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300714}
715
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300716static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
717 struct sk_buff *skb)
718{
719 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
720 struct amp_assoc *assoc = &hdev->loc_assoc;
721 size_t rem_len, frag_len;
722
723 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
724
725 if (rp->status)
726 goto a2mp_rsp;
727
728 frag_len = skb->len - sizeof(*rp);
729 rem_len = __le16_to_cpu(rp->rem_len);
730
731 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300732 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300733
734 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
735 assoc->offset += frag_len;
736
737 /* Read other fragments */
738 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
739
740 return;
741 }
742
743 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
744 assoc->len = assoc->offset + rem_len;
745 assoc->offset = 0;
746
747a2mp_rsp:
748 /* Send A2MP Rsp when all fragments are received */
749 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300750 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300751}
752
Johan Hedbergd5859e22011-01-25 01:19:58 +0200753static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300754 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200755{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700756 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200757
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300758 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200759
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700760 if (!rp->status)
761 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200762}
763
Johan Hedberg980e1a52011-01-22 06:10:07 +0200764static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
765{
766 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
767 struct hci_cp_pin_code_reply *cp;
768 struct hci_conn *conn;
769
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300770 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200771
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200772 hci_dev_lock(hdev);
773
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200774 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200775 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200776
Mikel Astizfa1bd912012-08-09 09:52:29 +0200777 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200778 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200779
780 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
781 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200782 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200783
784 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
785 if (conn)
786 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200787
788unlock:
789 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200790}
791
792static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
793{
794 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
795
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300796 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200797
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200798 hci_dev_lock(hdev);
799
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200800 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200801 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300802 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200803
804 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200805}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200806
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300807static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
808 struct sk_buff *skb)
809{
810 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
811
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300812 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300813
814 if (rp->status)
815 return;
816
817 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
818 hdev->le_pkts = rp->le_max_pkt;
819
820 hdev->le_cnt = hdev->le_pkts;
821
822 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300823}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200824
Johan Hedberg60e77322013-01-22 14:01:59 +0200825static void hci_cc_le_read_local_features(struct hci_dev *hdev,
826 struct sk_buff *skb)
827{
828 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
829
830 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
831
832 if (!rp->status)
833 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200834}
835
Johan Hedberg8fa19092012-10-19 20:57:49 +0300836static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
837 struct sk_buff *skb)
838{
839 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
840
841 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
842
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500843 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300844 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300845}
846
Johan Hedberga5c29682011-02-19 12:05:57 -0300847static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
848{
849 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
850
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300851 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300852
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200853 hci_dev_lock(hdev);
854
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200855 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300856 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
857 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200858
859 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300860}
861
862static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300863 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300864{
865 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
866
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300867 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300868
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200869 hci_dev_lock(hdev);
870
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200871 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200872 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300873 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200874
875 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300876}
877
Brian Gix1143d452011-11-23 08:28:34 -0800878static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
879{
880 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
881
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300882 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800883
884 hci_dev_lock(hdev);
885
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200886 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200887 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300888 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800889
890 hci_dev_unlock(hdev);
891}
892
893static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300894 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800895{
896 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
897
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300898 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800899
900 hci_dev_lock(hdev);
901
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200902 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800903 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300904 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800905
906 hci_dev_unlock(hdev);
907}
908
Szymon Jancc35938b2011-03-22 13:12:21 +0100909static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300910 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100911{
912 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
913
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300914 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100915
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200916 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +0200917 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +0100918 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200919 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100920}
921
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100922static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
923{
924 __u8 *sent, status = *((__u8 *) skb->data);
925
926 BT_DBG("%s status 0x%2.2x", hdev->name, status);
927
928 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
929 if (!sent)
930 return;
931
932 hci_dev_lock(hdev);
933
934 if (!status) {
935 if (*sent)
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200936 set_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100937 else
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200938 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100939 }
940
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500941 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100942}
943
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300944static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300945 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300946{
947 struct hci_cp_le_set_scan_enable *cp;
948 __u8 status = *((__u8 *) skb->data);
949
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300950 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300951
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300952 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
953 if (!cp)
954 return;
955
Andre Guedes3fd319b2013-04-30 15:29:36 -0300956 if (status)
957 return;
958
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200959 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -0300960 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300961 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200962 break;
963
Andre Guedes76a388b2013-04-04 20:21:02 -0300964 case LE_SCAN_DISABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300965 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200966 break;
967
968 default:
969 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
970 break;
Andre Guedes35815082011-05-26 16:23:53 -0300971 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300972}
973
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200974static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
975 struct sk_buff *skb)
976{
977 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
978
979 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
980
981 if (!rp->status)
982 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200983}
984
Johan Hedberg9b008c02013-01-22 14:02:01 +0200985static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
986 struct sk_buff *skb)
987{
988 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
989
990 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
991
992 if (!rp->status)
993 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +0200994}
995
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300996static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
997 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -0300998{
Johan Hedberg06199cf2012-02-22 16:37:11 +0200999 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001000 __u8 status = *((__u8 *) skb->data);
1001
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001002 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001003
Johan Hedberg06199cf2012-02-22 16:37:11 +02001004 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001005 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001006 return;
1007
Johan Hedberg8f984df2012-02-28 01:07:22 +02001008 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001009 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001010 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001011 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1012 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001013 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001014 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001015 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001016 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001017
1018 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001019 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001020 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001021 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001022 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001023}
1024
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001025static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1026 struct sk_buff *skb)
1027{
1028 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1029
1030 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1031 hdev->name, rp->status, rp->phy_handle);
1032
1033 if (rp->status)
1034 return;
1035
1036 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1037}
1038
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001039static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001040{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001041 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001042
1043 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001044 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001045 return;
1046 }
1047
Andre Guedes89352e72011-11-04 14:16:53 -03001048 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001049}
1050
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001051static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001053 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001056 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001057
1058 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059 if (!cp)
1060 return;
1061
1062 hci_dev_lock(hdev);
1063
1064 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1065
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001066 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067
1068 if (status) {
1069 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001070 if (status != 0x0c || conn->attempt > 2) {
1071 conn->state = BT_CLOSED;
1072 hci_proto_connect_cfm(conn, status);
1073 hci_conn_del(conn);
1074 } else
1075 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076 }
1077 } else {
1078 if (!conn) {
1079 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1080 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001081 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082 conn->link_mode |= HCI_LM_MASTER;
1083 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001084 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 }
1086 }
1087
1088 hci_dev_unlock(hdev);
1089}
1090
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001091static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001093 struct hci_cp_add_sco *cp;
1094 struct hci_conn *acl, *sco;
1095 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001097 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001098
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001099 if (!status)
1100 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001102 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1103 if (!cp)
1104 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001106 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001108 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001109
1110 hci_dev_lock(hdev);
1111
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001112 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001113 if (acl) {
1114 sco = acl->link;
1115 if (sco) {
1116 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001117
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001118 hci_proto_connect_cfm(sco, status);
1119 hci_conn_del(sco);
1120 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001121 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001122
1123 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124}
1125
Marcel Holtmannf8558552008-07-14 20:13:49 +02001126static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1127{
1128 struct hci_cp_auth_requested *cp;
1129 struct hci_conn *conn;
1130
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001131 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001132
1133 if (!status)
1134 return;
1135
1136 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1137 if (!cp)
1138 return;
1139
1140 hci_dev_lock(hdev);
1141
1142 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1143 if (conn) {
1144 if (conn->state == BT_CONFIG) {
1145 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001146 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001147 }
1148 }
1149
1150 hci_dev_unlock(hdev);
1151}
1152
1153static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1154{
1155 struct hci_cp_set_conn_encrypt *cp;
1156 struct hci_conn *conn;
1157
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001158 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001159
1160 if (!status)
1161 return;
1162
1163 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1164 if (!cp)
1165 return;
1166
1167 hci_dev_lock(hdev);
1168
1169 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1170 if (conn) {
1171 if (conn->state == BT_CONFIG) {
1172 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001173 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001174 }
1175 }
1176
1177 hci_dev_unlock(hdev);
1178}
1179
Johan Hedberg127178d2010-11-18 22:22:29 +02001180static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001181 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001182{
Johan Hedberg392599b2010-11-18 22:22:28 +02001183 if (conn->state != BT_CONFIG || !conn->out)
1184 return 0;
1185
Johan Hedberg765c2a92011-01-19 12:06:52 +05301186 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001187 return 0;
1188
1189 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001190 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001191 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1192 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001193 return 0;
1194
Johan Hedberg392599b2010-11-18 22:22:28 +02001195 return 1;
1196}
1197
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001198static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001199 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001200{
1201 struct hci_cp_remote_name_req cp;
1202
1203 memset(&cp, 0, sizeof(cp));
1204
1205 bacpy(&cp.bdaddr, &e->data.bdaddr);
1206 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1207 cp.pscan_mode = e->data.pscan_mode;
1208 cp.clock_offset = e->data.clock_offset;
1209
1210 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1211}
1212
Johan Hedbergb644ba32012-01-17 21:48:47 +02001213static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001214{
1215 struct discovery_state *discov = &hdev->discovery;
1216 struct inquiry_entry *e;
1217
Johan Hedbergb644ba32012-01-17 21:48:47 +02001218 if (list_empty(&discov->resolve))
1219 return false;
1220
1221 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001222 if (!e)
1223 return false;
1224
Johan Hedbergb644ba32012-01-17 21:48:47 +02001225 if (hci_resolve_name(hdev, e) == 0) {
1226 e->name_state = NAME_PENDING;
1227 return true;
1228 }
1229
1230 return false;
1231}
1232
1233static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001234 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001235{
1236 struct discovery_state *discov = &hdev->discovery;
1237 struct inquiry_entry *e;
1238
1239 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001240 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1241 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001242
1243 if (discov->state == DISCOVERY_STOPPED)
1244 return;
1245
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001246 if (discov->state == DISCOVERY_STOPPING)
1247 goto discov_complete;
1248
1249 if (discov->state != DISCOVERY_RESOLVING)
1250 return;
1251
1252 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001253 /* If the device was not found in a list of found devices names of which
1254 * are pending. there is no need to continue resolving a next name as it
1255 * will be done upon receiving another Remote Name Request Complete
1256 * Event */
1257 if (!e)
1258 return;
1259
1260 list_del(&e->list);
1261 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001262 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001263 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1264 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001265 } else {
1266 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001267 }
1268
Johan Hedbergb644ba32012-01-17 21:48:47 +02001269 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001270 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001271
1272discov_complete:
1273 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1274}
1275
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001276static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1277{
Johan Hedberg127178d2010-11-18 22:22:29 +02001278 struct hci_cp_remote_name_req *cp;
1279 struct hci_conn *conn;
1280
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001281 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001282
1283 /* If successful wait for the name req complete event before
1284 * checking for the need to do authentication */
1285 if (!status)
1286 return;
1287
1288 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1289 if (!cp)
1290 return;
1291
1292 hci_dev_lock(hdev);
1293
1294 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001295
1296 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1297 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1298
Johan Hedberg79c6c702011-04-28 11:28:55 -07001299 if (!conn)
1300 goto unlock;
1301
1302 if (!hci_outgoing_auth_needed(hdev, conn))
1303 goto unlock;
1304
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001305 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001306 struct hci_cp_auth_requested auth_cp;
1307
1308 auth_cp.handle = __cpu_to_le16(conn->handle);
1309 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1310 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001311 }
1312
Johan Hedberg79c6c702011-04-28 11:28:55 -07001313unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001314 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001315}
1316
Marcel Holtmann769be972008-07-14 20:13:49 +02001317static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1318{
1319 struct hci_cp_read_remote_features *cp;
1320 struct hci_conn *conn;
1321
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001322 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001323
1324 if (!status)
1325 return;
1326
1327 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1328 if (!cp)
1329 return;
1330
1331 hci_dev_lock(hdev);
1332
1333 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1334 if (conn) {
1335 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001336 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001337 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001338 }
1339 }
1340
1341 hci_dev_unlock(hdev);
1342}
1343
1344static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1345{
1346 struct hci_cp_read_remote_ext_features *cp;
1347 struct hci_conn *conn;
1348
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001349 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001350
1351 if (!status)
1352 return;
1353
1354 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1355 if (!cp)
1356 return;
1357
1358 hci_dev_lock(hdev);
1359
1360 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1361 if (conn) {
1362 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001363 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001364 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001365 }
1366 }
1367
1368 hci_dev_unlock(hdev);
1369}
1370
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001371static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1372{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001373 struct hci_cp_setup_sync_conn *cp;
1374 struct hci_conn *acl, *sco;
1375 __u16 handle;
1376
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001377 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001378
1379 if (!status)
1380 return;
1381
1382 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1383 if (!cp)
1384 return;
1385
1386 handle = __le16_to_cpu(cp->handle);
1387
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001388 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001389
1390 hci_dev_lock(hdev);
1391
1392 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001393 if (acl) {
1394 sco = acl->link;
1395 if (sco) {
1396 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001397
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001398 hci_proto_connect_cfm(sco, status);
1399 hci_conn_del(sco);
1400 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001401 }
1402
1403 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001404}
1405
1406static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1407{
1408 struct hci_cp_sniff_mode *cp;
1409 struct hci_conn *conn;
1410
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001411 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001412
1413 if (!status)
1414 return;
1415
1416 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1417 if (!cp)
1418 return;
1419
1420 hci_dev_lock(hdev);
1421
1422 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001423 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001424 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001425
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001426 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001427 hci_sco_setup(conn, status);
1428 }
1429
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001430 hci_dev_unlock(hdev);
1431}
1432
1433static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1434{
1435 struct hci_cp_exit_sniff_mode *cp;
1436 struct hci_conn *conn;
1437
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001438 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001439
1440 if (!status)
1441 return;
1442
1443 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1444 if (!cp)
1445 return;
1446
1447 hci_dev_lock(hdev);
1448
1449 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001450 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001451 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001452
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001453 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001454 hci_sco_setup(conn, status);
1455 }
1456
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001457 hci_dev_unlock(hdev);
1458}
1459
Johan Hedberg88c3df12012-02-09 14:27:38 +02001460static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1461{
1462 struct hci_cp_disconnect *cp;
1463 struct hci_conn *conn;
1464
1465 if (!status)
1466 return;
1467
1468 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1469 if (!cp)
1470 return;
1471
1472 hci_dev_lock(hdev);
1473
1474 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1475 if (conn)
1476 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001477 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001478
1479 hci_dev_unlock(hdev);
1480}
1481
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001482static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1483{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001484 struct hci_cp_create_phy_link *cp;
1485
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001486 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001487
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001488 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1489 if (!cp)
1490 return;
1491
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001492 hci_dev_lock(hdev);
1493
1494 if (status) {
1495 struct hci_conn *hcon;
1496
1497 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1498 if (hcon)
1499 hci_conn_del(hcon);
1500 } else {
1501 amp_write_remote_assoc(hdev, cp->phy_handle);
1502 }
1503
1504 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001505}
1506
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001507static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1508{
1509 struct hci_cp_accept_phy_link *cp;
1510
1511 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1512
1513 if (status)
1514 return;
1515
1516 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1517 if (!cp)
1518 return;
1519
1520 amp_write_remote_assoc(hdev, cp->phy_handle);
1521}
1522
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001523static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001524{
1525 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001526 struct discovery_state *discov = &hdev->discovery;
1527 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001528
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001529 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001530
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001531 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001532
1533 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1534 return;
1535
Andre Guedes3e13fa12013-03-27 20:04:56 -03001536 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1537 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1538
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001539 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001540 return;
1541
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001542 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001543
Andre Guedes343f9352012-02-17 20:39:37 -03001544 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001545 goto unlock;
1546
1547 if (list_empty(&discov->resolve)) {
1548 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1549 goto unlock;
1550 }
1551
1552 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1553 if (e && hci_resolve_name(hdev, e) == 0) {
1554 e->name_state = NAME_PENDING;
1555 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1556 } else {
1557 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1558 }
1559
1560unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001561 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001562}
1563
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001564static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001566 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001567 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568 int num_rsp = *((__u8 *) skb->data);
1569
1570 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1571
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001572 if (!num_rsp)
1573 return;
1574
Andre Guedes1519cc12012-03-21 00:03:38 -03001575 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1576 return;
1577
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001579
Johan Hedberge17acd42011-03-30 23:57:16 +03001580 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001581 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001582
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 bacpy(&data.bdaddr, &info->bdaddr);
1584 data.pscan_rep_mode = info->pscan_rep_mode;
1585 data.pscan_period_mode = info->pscan_period_mode;
1586 data.pscan_mode = info->pscan_mode;
1587 memcpy(data.dev_class, info->dev_class, 3);
1588 data.clock_offset = info->clock_offset;
1589 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001590 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001591
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001592 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001593 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001594 info->dev_class, 0, !name_known, ssp, NULL,
1595 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001597
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 hci_dev_unlock(hdev);
1599}
1600
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001601static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001603 struct hci_ev_conn_complete *ev = (void *) skb->data;
1604 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001606 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001607
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001609
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001610 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001611 if (!conn) {
1612 if (ev->link_type != SCO_LINK)
1613 goto unlock;
1614
1615 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1616 if (!conn)
1617 goto unlock;
1618
1619 conn->type = SCO_LINK;
1620 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001621
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001622 if (!ev->status) {
1623 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001624
1625 if (conn->type == ACL_LINK) {
1626 conn->state = BT_CONFIG;
1627 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001628
1629 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1630 !hci_find_link_key(hdev, &ev->bdaddr))
1631 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1632 else
1633 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001634 } else
1635 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001636
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001637 hci_conn_add_sysfs(conn);
1638
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001639 if (test_bit(HCI_AUTH, &hdev->flags))
1640 conn->link_mode |= HCI_LM_AUTH;
1641
1642 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1643 conn->link_mode |= HCI_LM_ENCRYPT;
1644
1645 /* Get remote features */
1646 if (conn->type == ACL_LINK) {
1647 struct hci_cp_read_remote_features cp;
1648 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001649 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001650 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001651 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001652
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001653 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001654 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001655 struct hci_cp_change_conn_ptype cp;
1656 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001657 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001658 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1659 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001660 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001661 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001662 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001663 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001664 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001665 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001666 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001667
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001668 if (conn->type == ACL_LINK)
1669 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001670
Marcel Holtmann769be972008-07-14 20:13:49 +02001671 if (ev->status) {
1672 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001673 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001674 } else if (ev->link_type != ACL_LINK)
1675 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001676
1677unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001679
1680 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681}
1682
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001683static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001685 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001687 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001689 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001690 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001692 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1693 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694
Szymon Janc138d22e2011-02-17 16:44:23 +01001695 if ((mask & HCI_LM_ACCEPT) &&
Marcel Holtmannb9ee0a72013-10-17 17:24:13 -07001696 !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001698 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700
1701 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001702
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001703 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1704 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001705 memcpy(ie->data.dev_class, ev->dev_class, 3);
1706
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001707 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1708 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001710 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1711 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001712 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713 hci_dev_unlock(hdev);
1714 return;
1715 }
1716 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001717
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001719
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 hci_dev_unlock(hdev);
1721
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001722 if (ev->link_type == ACL_LINK ||
1723 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001724 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001725 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001727 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001729 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1730 cp.role = 0x00; /* Become master */
1731 else
1732 cp.role = 0x01; /* Remain slave */
1733
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001734 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1735 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001736 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001737 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001738 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001739
1740 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001741 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001742
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001743 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1744 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1745 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001746 cp.content_format = cpu_to_le16(hdev->voice_setting);
1747 cp.retrans_effort = 0xff;
1748
1749 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001750 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001751 } else {
1752 conn->state = BT_CONNECT2;
1753 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001754 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 } else {
1756 /* Connection rejected */
1757 struct hci_cp_reject_conn_req cp;
1758
1759 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001760 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001761 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762 }
1763}
1764
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001765static u8 hci_to_mgmt_reason(u8 err)
1766{
1767 switch (err) {
1768 case HCI_ERROR_CONNECTION_TIMEOUT:
1769 return MGMT_DEV_DISCONN_TIMEOUT;
1770 case HCI_ERROR_REMOTE_USER_TERM:
1771 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1772 case HCI_ERROR_REMOTE_POWER_OFF:
1773 return MGMT_DEV_DISCONN_REMOTE;
1774 case HCI_ERROR_LOCAL_HOST_TERM:
1775 return MGMT_DEV_DISCONN_LOCAL_HOST;
1776 default:
1777 return MGMT_DEV_DISCONN_UNKNOWN;
1778 }
1779}
1780
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001781static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001783 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001784 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001786 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 hci_dev_lock(hdev);
1789
Marcel Holtmann04837f62006-07-03 10:02:33 +02001790 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001791 if (!conn)
1792 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001793
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001794 if (ev->status == 0)
1795 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796
Johan Hedbergb644ba32012-01-17 21:48:47 +02001797 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001798 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001799 if (ev->status) {
Johan Hedberg88c3df12012-02-09 14:27:38 +02001800 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001801 conn->dst_type, ev->status);
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001802 } else {
1803 u8 reason = hci_to_mgmt_reason(ev->reason);
1804
Johan Hedbergafc747a2012-01-15 18:11:07 +02001805 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001806 conn->dst_type, reason);
1807 }
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001808 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001809
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001810 if (ev->status == 0) {
Johan Hedberg22102462013-10-05 12:01:06 +02001811 u8 type = conn->type;
1812
1813 if (type == ACL_LINK && conn->flush_key)
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301814 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001815 hci_proto_disconn_cfm(conn, ev->reason);
1816 hci_conn_del(conn);
Johan Hedberg22102462013-10-05 12:01:06 +02001817
1818 /* Re-enable advertising if necessary, since it might
1819 * have been disabled by the connection. From the
1820 * HCI_LE_Set_Advertise_Enable command description in
1821 * the core specification (v4.0):
1822 * "The Controller shall continue advertising until the Host
1823 * issues an LE_Set_Advertise_Enable command with
1824 * Advertising_Enable set to 0x00 (Advertising is disabled)
1825 * or until a connection is created or until the Advertising
1826 * is timed out due to Directed Advertising."
1827 */
1828 if (type == LE_LINK)
Marcel Holtmann5976e602013-10-06 04:08:14 -07001829 mgmt_reenable_advertising(hdev);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001830 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001831
1832unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 hci_dev_unlock(hdev);
1834}
1835
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001836static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001837{
1838 struct hci_ev_auth_complete *ev = (void *) skb->data;
1839 struct hci_conn *conn;
1840
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001841 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001842
1843 hci_dev_lock(hdev);
1844
1845 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001846 if (!conn)
1847 goto unlock;
1848
1849 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001850 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001851 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001852 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001853 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001854 conn->link_mode |= HCI_LM_AUTH;
1855 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001856 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001857 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001858 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001859 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001860 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001861
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001862 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1863 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001864
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001865 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001866 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001867 struct hci_cp_set_conn_encrypt cp;
1868 cp.handle = ev->handle;
1869 cp.encrypt = 0x01;
1870 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001871 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001872 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001873 conn->state = BT_CONNECTED;
1874 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001875 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001876 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001877 } else {
1878 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001879
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001880 hci_conn_hold(conn);
1881 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001882 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001883 }
1884
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001885 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001886 if (!ev->status) {
1887 struct hci_cp_set_conn_encrypt cp;
1888 cp.handle = ev->handle;
1889 cp.encrypt = 0x01;
1890 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001891 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001892 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001893 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001894 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001895 }
1896 }
1897
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001898unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001899 hci_dev_unlock(hdev);
1900}
1901
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001902static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001903{
Johan Hedberg127178d2010-11-18 22:22:29 +02001904 struct hci_ev_remote_name *ev = (void *) skb->data;
1905 struct hci_conn *conn;
1906
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001907 BT_DBG("%s", hdev->name);
1908
1909 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001910
1911 hci_dev_lock(hdev);
1912
1913 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001914
1915 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1916 goto check_auth;
1917
1918 if (ev->status == 0)
1919 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001920 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001921 else
1922 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1923
1924check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001925 if (!conn)
1926 goto unlock;
1927
1928 if (!hci_outgoing_auth_needed(hdev, conn))
1929 goto unlock;
1930
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001931 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001932 struct hci_cp_auth_requested cp;
1933 cp.handle = __cpu_to_le16(conn->handle);
1934 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1935 }
1936
Johan Hedberg79c6c702011-04-28 11:28:55 -07001937unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001938 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001939}
1940
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001941static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001942{
1943 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1944 struct hci_conn *conn;
1945
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001946 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001947
1948 hci_dev_lock(hdev);
1949
1950 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1951 if (conn) {
1952 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001953 if (ev->encrypt) {
1954 /* Encryption implies authentication */
1955 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001956 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001957 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001958 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001959 conn->link_mode &= ~HCI_LM_ENCRYPT;
1960 }
1961
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001962 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001963
Gustavo Padovana7d77232012-05-13 03:20:07 -03001964 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03001965 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02001966 hci_conn_drop(conn);
Gustavo Padovana7d77232012-05-13 03:20:07 -03001967 goto unlock;
1968 }
1969
Marcel Holtmannf8558552008-07-14 20:13:49 +02001970 if (conn->state == BT_CONFIG) {
1971 if (!ev->status)
1972 conn->state = BT_CONNECTED;
1973
1974 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001975 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001976 } else
1977 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001978 }
1979
Gustavo Padovana7d77232012-05-13 03:20:07 -03001980unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001981 hci_dev_unlock(hdev);
1982}
1983
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001984static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
1985 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001986{
1987 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1988 struct hci_conn *conn;
1989
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001990 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001991
1992 hci_dev_lock(hdev);
1993
1994 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1995 if (conn) {
1996 if (!ev->status)
1997 conn->link_mode |= HCI_LM_SECURE;
1998
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001999 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002000
2001 hci_key_change_cfm(conn, ev->status);
2002 }
2003
2004 hci_dev_unlock(hdev);
2005}
2006
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002007static void hci_remote_features_evt(struct hci_dev *hdev,
2008 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002009{
2010 struct hci_ev_remote_features *ev = (void *) skb->data;
2011 struct hci_conn *conn;
2012
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002013 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002014
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002015 hci_dev_lock(hdev);
2016
2017 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002018 if (!conn)
2019 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002020
Johan Hedbergccd556f2010-11-10 17:11:51 +02002021 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002022 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002023
2024 if (conn->state != BT_CONFIG)
2025 goto unlock;
2026
2027 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2028 struct hci_cp_read_remote_ext_features cp;
2029 cp.handle = ev->handle;
2030 cp.page = 0x01;
2031 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002032 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002033 goto unlock;
2034 }
2035
Johan Hedberg671267b2012-05-12 16:11:50 -03002036 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002037 struct hci_cp_remote_name_req cp;
2038 memset(&cp, 0, sizeof(cp));
2039 bacpy(&cp.bdaddr, &conn->dst);
2040 cp.pscan_rep_mode = 0x02;
2041 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002042 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2043 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002044 conn->dst_type, 0, NULL, 0,
2045 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002046
Johan Hedberg127178d2010-11-18 22:22:29 +02002047 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002048 conn->state = BT_CONNECTED;
2049 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002050 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002051 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002052
Johan Hedbergccd556f2010-11-10 17:11:51 +02002053unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002054 hci_dev_unlock(hdev);
2055}
2056
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002057static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002058{
2059 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002060 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002061 __u16 opcode;
2062
2063 skb_pull(skb, sizeof(*ev));
2064
2065 opcode = __le16_to_cpu(ev->opcode);
2066
2067 switch (opcode) {
2068 case HCI_OP_INQUIRY_CANCEL:
2069 hci_cc_inquiry_cancel(hdev, skb);
2070 break;
2071
Andre Guedes4d934832012-03-21 00:03:35 -03002072 case HCI_OP_PERIODIC_INQ:
2073 hci_cc_periodic_inq(hdev, skb);
2074 break;
2075
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002076 case HCI_OP_EXIT_PERIODIC_INQ:
2077 hci_cc_exit_periodic_inq(hdev, skb);
2078 break;
2079
2080 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2081 hci_cc_remote_name_req_cancel(hdev, skb);
2082 break;
2083
2084 case HCI_OP_ROLE_DISCOVERY:
2085 hci_cc_role_discovery(hdev, skb);
2086 break;
2087
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002088 case HCI_OP_READ_LINK_POLICY:
2089 hci_cc_read_link_policy(hdev, skb);
2090 break;
2091
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002092 case HCI_OP_WRITE_LINK_POLICY:
2093 hci_cc_write_link_policy(hdev, skb);
2094 break;
2095
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002096 case HCI_OP_READ_DEF_LINK_POLICY:
2097 hci_cc_read_def_link_policy(hdev, skb);
2098 break;
2099
2100 case HCI_OP_WRITE_DEF_LINK_POLICY:
2101 hci_cc_write_def_link_policy(hdev, skb);
2102 break;
2103
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002104 case HCI_OP_RESET:
2105 hci_cc_reset(hdev, skb);
2106 break;
2107
2108 case HCI_OP_WRITE_LOCAL_NAME:
2109 hci_cc_write_local_name(hdev, skb);
2110 break;
2111
2112 case HCI_OP_READ_LOCAL_NAME:
2113 hci_cc_read_local_name(hdev, skb);
2114 break;
2115
2116 case HCI_OP_WRITE_AUTH_ENABLE:
2117 hci_cc_write_auth_enable(hdev, skb);
2118 break;
2119
2120 case HCI_OP_WRITE_ENCRYPT_MODE:
2121 hci_cc_write_encrypt_mode(hdev, skb);
2122 break;
2123
2124 case HCI_OP_WRITE_SCAN_ENABLE:
2125 hci_cc_write_scan_enable(hdev, skb);
2126 break;
2127
2128 case HCI_OP_READ_CLASS_OF_DEV:
2129 hci_cc_read_class_of_dev(hdev, skb);
2130 break;
2131
2132 case HCI_OP_WRITE_CLASS_OF_DEV:
2133 hci_cc_write_class_of_dev(hdev, skb);
2134 break;
2135
2136 case HCI_OP_READ_VOICE_SETTING:
2137 hci_cc_read_voice_setting(hdev, skb);
2138 break;
2139
2140 case HCI_OP_WRITE_VOICE_SETTING:
2141 hci_cc_write_voice_setting(hdev, skb);
2142 break;
2143
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002144 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2145 hci_cc_read_num_supported_iac(hdev, skb);
2146 break;
2147
Marcel Holtmann333140b2008-07-14 20:13:48 +02002148 case HCI_OP_WRITE_SSP_MODE:
2149 hci_cc_write_ssp_mode(hdev, skb);
2150 break;
2151
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002152 case HCI_OP_READ_LOCAL_VERSION:
2153 hci_cc_read_local_version(hdev, skb);
2154 break;
2155
2156 case HCI_OP_READ_LOCAL_COMMANDS:
2157 hci_cc_read_local_commands(hdev, skb);
2158 break;
2159
2160 case HCI_OP_READ_LOCAL_FEATURES:
2161 hci_cc_read_local_features(hdev, skb);
2162 break;
2163
Andre Guedes971e3a42011-06-30 19:20:52 -03002164 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2165 hci_cc_read_local_ext_features(hdev, skb);
2166 break;
2167
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002168 case HCI_OP_READ_BUFFER_SIZE:
2169 hci_cc_read_buffer_size(hdev, skb);
2170 break;
2171
2172 case HCI_OP_READ_BD_ADDR:
2173 hci_cc_read_bd_addr(hdev, skb);
2174 break;
2175
Johan Hedbergf332ec62013-03-15 17:07:11 -05002176 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2177 hci_cc_read_page_scan_activity(hdev, skb);
2178 break;
2179
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002180 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2181 hci_cc_write_page_scan_activity(hdev, skb);
2182 break;
2183
Johan Hedbergf332ec62013-03-15 17:07:11 -05002184 case HCI_OP_READ_PAGE_SCAN_TYPE:
2185 hci_cc_read_page_scan_type(hdev, skb);
2186 break;
2187
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002188 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2189 hci_cc_write_page_scan_type(hdev, skb);
2190 break;
2191
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002192 case HCI_OP_READ_DATA_BLOCK_SIZE:
2193 hci_cc_read_data_block_size(hdev, skb);
2194 break;
2195
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002196 case HCI_OP_READ_FLOW_CONTROL_MODE:
2197 hci_cc_read_flow_control_mode(hdev, skb);
2198 break;
2199
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002200 case HCI_OP_READ_LOCAL_AMP_INFO:
2201 hci_cc_read_local_amp_info(hdev, skb);
2202 break;
2203
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002204 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2205 hci_cc_read_local_amp_assoc(hdev, skb);
2206 break;
2207
Johan Hedbergd5859e22011-01-25 01:19:58 +02002208 case HCI_OP_READ_INQ_RSP_TX_POWER:
2209 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2210 break;
2211
Johan Hedberg980e1a52011-01-22 06:10:07 +02002212 case HCI_OP_PIN_CODE_REPLY:
2213 hci_cc_pin_code_reply(hdev, skb);
2214 break;
2215
2216 case HCI_OP_PIN_CODE_NEG_REPLY:
2217 hci_cc_pin_code_neg_reply(hdev, skb);
2218 break;
2219
Szymon Jancc35938b2011-03-22 13:12:21 +01002220 case HCI_OP_READ_LOCAL_OOB_DATA:
2221 hci_cc_read_local_oob_data_reply(hdev, skb);
2222 break;
2223
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002224 case HCI_OP_LE_READ_BUFFER_SIZE:
2225 hci_cc_le_read_buffer_size(hdev, skb);
2226 break;
2227
Johan Hedberg60e77322013-01-22 14:01:59 +02002228 case HCI_OP_LE_READ_LOCAL_FEATURES:
2229 hci_cc_le_read_local_features(hdev, skb);
2230 break;
2231
Johan Hedberg8fa19092012-10-19 20:57:49 +03002232 case HCI_OP_LE_READ_ADV_TX_POWER:
2233 hci_cc_le_read_adv_tx_power(hdev, skb);
2234 break;
2235
Johan Hedberga5c29682011-02-19 12:05:57 -03002236 case HCI_OP_USER_CONFIRM_REPLY:
2237 hci_cc_user_confirm_reply(hdev, skb);
2238 break;
2239
2240 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2241 hci_cc_user_confirm_neg_reply(hdev, skb);
2242 break;
2243
Brian Gix1143d452011-11-23 08:28:34 -08002244 case HCI_OP_USER_PASSKEY_REPLY:
2245 hci_cc_user_passkey_reply(hdev, skb);
2246 break;
2247
2248 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2249 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002250 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002251
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002252 case HCI_OP_LE_SET_ADV_ENABLE:
2253 hci_cc_le_set_adv_enable(hdev, skb);
2254 break;
2255
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002256 case HCI_OP_LE_SET_SCAN_ENABLE:
2257 hci_cc_le_set_scan_enable(hdev, skb);
2258 break;
2259
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002260 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2261 hci_cc_le_read_white_list_size(hdev, skb);
2262 break;
2263
Johan Hedberg9b008c02013-01-22 14:02:01 +02002264 case HCI_OP_LE_READ_SUPPORTED_STATES:
2265 hci_cc_le_read_supported_states(hdev, skb);
2266 break;
2267
Andre Guedesf9b49302011-06-30 19:20:53 -03002268 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2269 hci_cc_write_le_host_supported(hdev, skb);
2270 break;
2271
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002272 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2273 hci_cc_write_remote_amp_assoc(hdev, skb);
2274 break;
2275
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002276 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002277 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002278 break;
2279 }
2280
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002281 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002282 del_timer(&hdev->cmd_timer);
2283
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002284 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002285
Szymon Jancdbccd792012-12-11 08:51:19 +01002286 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002287 atomic_set(&hdev->cmd_cnt, 1);
2288 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002289 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002290 }
2291}
2292
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002293static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002294{
2295 struct hci_ev_cmd_status *ev = (void *) skb->data;
2296 __u16 opcode;
2297
2298 skb_pull(skb, sizeof(*ev));
2299
2300 opcode = __le16_to_cpu(ev->opcode);
2301
2302 switch (opcode) {
2303 case HCI_OP_INQUIRY:
2304 hci_cs_inquiry(hdev, ev->status);
2305 break;
2306
2307 case HCI_OP_CREATE_CONN:
2308 hci_cs_create_conn(hdev, ev->status);
2309 break;
2310
2311 case HCI_OP_ADD_SCO:
2312 hci_cs_add_sco(hdev, ev->status);
2313 break;
2314
Marcel Holtmannf8558552008-07-14 20:13:49 +02002315 case HCI_OP_AUTH_REQUESTED:
2316 hci_cs_auth_requested(hdev, ev->status);
2317 break;
2318
2319 case HCI_OP_SET_CONN_ENCRYPT:
2320 hci_cs_set_conn_encrypt(hdev, ev->status);
2321 break;
2322
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002323 case HCI_OP_REMOTE_NAME_REQ:
2324 hci_cs_remote_name_req(hdev, ev->status);
2325 break;
2326
Marcel Holtmann769be972008-07-14 20:13:49 +02002327 case HCI_OP_READ_REMOTE_FEATURES:
2328 hci_cs_read_remote_features(hdev, ev->status);
2329 break;
2330
2331 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2332 hci_cs_read_remote_ext_features(hdev, ev->status);
2333 break;
2334
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002335 case HCI_OP_SETUP_SYNC_CONN:
2336 hci_cs_setup_sync_conn(hdev, ev->status);
2337 break;
2338
2339 case HCI_OP_SNIFF_MODE:
2340 hci_cs_sniff_mode(hdev, ev->status);
2341 break;
2342
2343 case HCI_OP_EXIT_SNIFF_MODE:
2344 hci_cs_exit_sniff_mode(hdev, ev->status);
2345 break;
2346
Johan Hedberg8962ee72011-01-20 12:40:27 +02002347 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002348 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002349 break;
2350
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002351 case HCI_OP_CREATE_PHY_LINK:
2352 hci_cs_create_phylink(hdev, ev->status);
2353 break;
2354
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002355 case HCI_OP_ACCEPT_PHY_LINK:
2356 hci_cs_accept_phylink(hdev, ev->status);
2357 break;
2358
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002359 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002360 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002361 break;
2362 }
2363
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002364 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002365 del_timer(&hdev->cmd_timer);
2366
Johan Hedberg02350a72013-04-03 21:50:29 +03002367 if (ev->status ||
2368 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2369 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002370
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002371 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002372 atomic_set(&hdev->cmd_cnt, 1);
2373 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002374 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002375 }
2376}
2377
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002378static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002379{
2380 struct hci_ev_role_change *ev = (void *) skb->data;
2381 struct hci_conn *conn;
2382
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002383 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002384
2385 hci_dev_lock(hdev);
2386
2387 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2388 if (conn) {
2389 if (!ev->status) {
2390 if (ev->role)
2391 conn->link_mode &= ~HCI_LM_MASTER;
2392 else
2393 conn->link_mode |= HCI_LM_MASTER;
2394 }
2395
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002396 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002397
2398 hci_role_switch_cfm(conn, ev->status, ev->role);
2399 }
2400
2401 hci_dev_unlock(hdev);
2402}
2403
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002404static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002406 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002407 int i;
2408
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002409 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2410 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2411 return;
2412 }
2413
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002414 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002415 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002416 BT_DBG("%s bad parameters", hdev->name);
2417 return;
2418 }
2419
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002420 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2421
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002422 for (i = 0; i < ev->num_hndl; i++) {
2423 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424 struct hci_conn *conn;
2425 __u16 handle, count;
2426
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002427 handle = __le16_to_cpu(info->handle);
2428 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002429
2430 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002431 if (!conn)
2432 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002433
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002434 conn->sent -= count;
2435
2436 switch (conn->type) {
2437 case ACL_LINK:
2438 hdev->acl_cnt += count;
2439 if (hdev->acl_cnt > hdev->acl_pkts)
2440 hdev->acl_cnt = hdev->acl_pkts;
2441 break;
2442
2443 case LE_LINK:
2444 if (hdev->le_pkts) {
2445 hdev->le_cnt += count;
2446 if (hdev->le_cnt > hdev->le_pkts)
2447 hdev->le_cnt = hdev->le_pkts;
2448 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002449 hdev->acl_cnt += count;
2450 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002451 hdev->acl_cnt = hdev->acl_pkts;
2452 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002453 break;
2454
2455 case SCO_LINK:
2456 hdev->sco_cnt += count;
2457 if (hdev->sco_cnt > hdev->sco_pkts)
2458 hdev->sco_cnt = hdev->sco_pkts;
2459 break;
2460
2461 default:
2462 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2463 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002464 }
2465 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002466
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002467 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002468}
2469
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002470static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2471 __u16 handle)
2472{
2473 struct hci_chan *chan;
2474
2475 switch (hdev->dev_type) {
2476 case HCI_BREDR:
2477 return hci_conn_hash_lookup_handle(hdev, handle);
2478 case HCI_AMP:
2479 chan = hci_chan_lookup_handle(hdev, handle);
2480 if (chan)
2481 return chan->conn;
2482 break;
2483 default:
2484 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2485 break;
2486 }
2487
2488 return NULL;
2489}
2490
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002491static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002492{
2493 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2494 int i;
2495
2496 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2497 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2498 return;
2499 }
2500
2501 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002502 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002503 BT_DBG("%s bad parameters", hdev->name);
2504 return;
2505 }
2506
2507 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002508 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002509
2510 for (i = 0; i < ev->num_hndl; i++) {
2511 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002512 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002513 __u16 handle, block_count;
2514
2515 handle = __le16_to_cpu(info->handle);
2516 block_count = __le16_to_cpu(info->blocks);
2517
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002518 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002519 if (!conn)
2520 continue;
2521
2522 conn->sent -= block_count;
2523
2524 switch (conn->type) {
2525 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002526 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002527 hdev->block_cnt += block_count;
2528 if (hdev->block_cnt > hdev->num_blocks)
2529 hdev->block_cnt = hdev->num_blocks;
2530 break;
2531
2532 default:
2533 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2534 break;
2535 }
2536 }
2537
2538 queue_work(hdev->workqueue, &hdev->tx_work);
2539}
2540
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002541static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002542{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002543 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002544 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002545
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002546 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002547
2548 hci_dev_lock(hdev);
2549
Marcel Holtmann04837f62006-07-03 10:02:33 +02002550 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2551 if (conn) {
2552 conn->mode = ev->mode;
2553 conn->interval = __le16_to_cpu(ev->interval);
2554
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002555 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2556 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002557 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002558 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002559 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002560 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002561 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002562
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002563 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002564 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002565 }
2566
2567 hci_dev_unlock(hdev);
2568}
2569
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002570static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002571{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002572 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2573 struct hci_conn *conn;
2574
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002575 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002576
2577 hci_dev_lock(hdev);
2578
2579 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002580 if (!conn)
2581 goto unlock;
2582
2583 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002584 hci_conn_hold(conn);
2585 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002586 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002587 }
2588
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002589 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002590 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002591 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002592 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002593 u8 secure;
2594
2595 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2596 secure = 1;
2597 else
2598 secure = 0;
2599
Johan Hedberg744cf192011-11-08 20:40:14 +02002600 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002601 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002602
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002603unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002604 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002605}
2606
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002607static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002608{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002609 struct hci_ev_link_key_req *ev = (void *) skb->data;
2610 struct hci_cp_link_key_reply cp;
2611 struct hci_conn *conn;
2612 struct link_key *key;
2613
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002614 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002615
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002616 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002617 return;
2618
2619 hci_dev_lock(hdev);
2620
2621 key = hci_find_link_key(hdev, &ev->bdaddr);
2622 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002623 BT_DBG("%s link key not found for %pMR", hdev->name,
2624 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002625 goto not_found;
2626 }
2627
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002628 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2629 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002630
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002631 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002632 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002633 BT_DBG("%s ignoring debug key", hdev->name);
2634 goto not_found;
2635 }
2636
2637 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002638 if (conn) {
2639 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002640 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002641 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2642 goto not_found;
2643 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002644
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002645 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002646 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002647 BT_DBG("%s ignoring key unauthenticated for high security",
2648 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002649 goto not_found;
2650 }
2651
2652 conn->key_type = key->type;
2653 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002654 }
2655
2656 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002657 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002658
2659 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2660
2661 hci_dev_unlock(hdev);
2662
2663 return;
2664
2665not_found:
2666 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2667 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002668}
2669
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002670static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002671{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002672 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2673 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002674 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002675
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002676 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002677
2678 hci_dev_lock(hdev);
2679
2680 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2681 if (conn) {
2682 hci_conn_hold(conn);
2683 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002684 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002685
2686 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2687 conn->key_type = ev->key_type;
2688
David Herrmann76a68ba2013-04-06 20:28:37 +02002689 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002690 }
2691
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002692 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002693 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002694 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002695
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002696 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002697}
2698
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002699static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002700{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002701 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002702 struct hci_conn *conn;
2703
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002704 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002705
2706 hci_dev_lock(hdev);
2707
2708 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002709 if (conn && !ev->status) {
2710 struct inquiry_entry *ie;
2711
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002712 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2713 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002714 ie->data.clock_offset = ev->clock_offset;
2715 ie->timestamp = jiffies;
2716 }
2717 }
2718
2719 hci_dev_unlock(hdev);
2720}
2721
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002722static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002723{
2724 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2725 struct hci_conn *conn;
2726
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002727 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002728
2729 hci_dev_lock(hdev);
2730
2731 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2732 if (conn && !ev->status)
2733 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2734
2735 hci_dev_unlock(hdev);
2736}
2737
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002738static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002739{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002740 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002741 struct inquiry_entry *ie;
2742
2743 BT_DBG("%s", hdev->name);
2744
2745 hci_dev_lock(hdev);
2746
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002747 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2748 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002749 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2750 ie->timestamp = jiffies;
2751 }
2752
2753 hci_dev_unlock(hdev);
2754}
2755
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002756static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2757 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002758{
2759 struct inquiry_data data;
2760 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002761 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002762
2763 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2764
2765 if (!num_rsp)
2766 return;
2767
Andre Guedes1519cc12012-03-21 00:03:38 -03002768 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2769 return;
2770
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002771 hci_dev_lock(hdev);
2772
2773 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002774 struct inquiry_info_with_rssi_and_pscan_mode *info;
2775 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002776
Johan Hedberge17acd42011-03-30 23:57:16 +03002777 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002778 bacpy(&data.bdaddr, &info->bdaddr);
2779 data.pscan_rep_mode = info->pscan_rep_mode;
2780 data.pscan_period_mode = info->pscan_period_mode;
2781 data.pscan_mode = info->pscan_mode;
2782 memcpy(data.dev_class, info->dev_class, 3);
2783 data.clock_offset = info->clock_offset;
2784 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002785 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002786
2787 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002788 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002789 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002790 info->dev_class, info->rssi,
2791 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002792 }
2793 } else {
2794 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2795
Johan Hedberge17acd42011-03-30 23:57:16 +03002796 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002797 bacpy(&data.bdaddr, &info->bdaddr);
2798 data.pscan_rep_mode = info->pscan_rep_mode;
2799 data.pscan_period_mode = info->pscan_period_mode;
2800 data.pscan_mode = 0x00;
2801 memcpy(data.dev_class, info->dev_class, 3);
2802 data.clock_offset = info->clock_offset;
2803 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002804 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002805 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002806 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002807 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002808 info->dev_class, info->rssi,
2809 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002810 }
2811 }
2812
2813 hci_dev_unlock(hdev);
2814}
2815
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002816static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2817 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002818{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002819 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2820 struct hci_conn *conn;
2821
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002822 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002823
Marcel Holtmann41a96212008-07-14 20:13:48 +02002824 hci_dev_lock(hdev);
2825
2826 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002827 if (!conn)
2828 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002829
Johan Hedbergcad718e2013-04-17 15:00:51 +03002830 if (ev->page < HCI_MAX_PAGES)
2831 memcpy(conn->features[ev->page], ev->features, 8);
2832
Johan Hedbergccd556f2010-11-10 17:11:51 +02002833 if (!ev->status && ev->page == 0x01) {
2834 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002835
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002836 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2837 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002838 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002839
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302840 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002841 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302842 } else {
2843 /* It is mandatory by the Bluetooth specification that
2844 * Extended Inquiry Results are only used when Secure
2845 * Simple Pairing is enabled, but some devices violate
2846 * this.
2847 *
2848 * To make these devices work, the internal SSP
2849 * enabled flag needs to be cleared if the remote host
2850 * features do not indicate SSP support */
2851 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2852 }
Marcel Holtmann41a96212008-07-14 20:13:48 +02002853 }
2854
Johan Hedbergccd556f2010-11-10 17:11:51 +02002855 if (conn->state != BT_CONFIG)
2856 goto unlock;
2857
Johan Hedberg671267b2012-05-12 16:11:50 -03002858 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002859 struct hci_cp_remote_name_req cp;
2860 memset(&cp, 0, sizeof(cp));
2861 bacpy(&cp.bdaddr, &conn->dst);
2862 cp.pscan_rep_mode = 0x02;
2863 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002864 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2865 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002866 conn->dst_type, 0, NULL, 0,
2867 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002868
Johan Hedberg127178d2010-11-18 22:22:29 +02002869 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002870 conn->state = BT_CONNECTED;
2871 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002872 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002873 }
2874
2875unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002876 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002877}
2878
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002879static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2880 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002881{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002882 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2883 struct hci_conn *conn;
2884
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002885 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002886
2887 hci_dev_lock(hdev);
2888
2889 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002890 if (!conn) {
2891 if (ev->link_type == ESCO_LINK)
2892 goto unlock;
2893
2894 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2895 if (!conn)
2896 goto unlock;
2897
2898 conn->type = SCO_LINK;
2899 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002900
Marcel Holtmann732547f2009-04-19 19:14:14 +02002901 switch (ev->status) {
2902 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002903 conn->handle = __le16_to_cpu(ev->handle);
2904 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002905
2906 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002907 break;
2908
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02002909 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05002910 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002911 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002912 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002913 case 0x1f: /* Unspecified error */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002914 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02002915 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2916 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002917 if (hci_setup_sync(conn, conn->link->handle))
2918 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002919 }
2920 /* fall through */
2921
2922 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002923 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002924 break;
2925 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002926
2927 hci_proto_connect_cfm(conn, ev->status);
2928 if (ev->status)
2929 hci_conn_del(conn);
2930
2931unlock:
2932 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002933}
2934
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07002935static inline size_t eir_get_length(u8 *eir, size_t eir_len)
2936{
2937 size_t parsed = 0;
2938
2939 while (parsed < eir_len) {
2940 u8 field_len = eir[0];
2941
2942 if (field_len == 0)
2943 return parsed;
2944
2945 parsed += field_len + 1;
2946 eir += field_len + 1;
2947 }
2948
2949 return eir_len;
2950}
2951
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002952static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
2953 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002954{
2955 struct inquiry_data data;
2956 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2957 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302958 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002959
2960 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2961
2962 if (!num_rsp)
2963 return;
2964
Andre Guedes1519cc12012-03-21 00:03:38 -03002965 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2966 return;
2967
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002968 hci_dev_lock(hdev);
2969
Johan Hedberge17acd42011-03-30 23:57:16 +03002970 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002971 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002972
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002973 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002974 data.pscan_rep_mode = info->pscan_rep_mode;
2975 data.pscan_period_mode = info->pscan_period_mode;
2976 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002977 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002978 data.clock_offset = info->clock_offset;
2979 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002980 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002981
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002982 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002983 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002984 sizeof(info->data),
2985 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002986 else
2987 name_known = true;
2988
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002989 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002990 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302991 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02002992 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002993 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302994 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002995 }
2996
2997 hci_dev_unlock(hdev);
2998}
2999
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003000static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3001 struct sk_buff *skb)
3002{
3003 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3004 struct hci_conn *conn;
3005
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003006 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003007 __le16_to_cpu(ev->handle));
3008
3009 hci_dev_lock(hdev);
3010
3011 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3012 if (!conn)
3013 goto unlock;
3014
3015 if (!ev->status)
3016 conn->sec_level = conn->pending_sec_level;
3017
3018 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3019
3020 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003021 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003022 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003023 goto unlock;
3024 }
3025
3026 if (conn->state == BT_CONFIG) {
3027 if (!ev->status)
3028 conn->state = BT_CONNECTED;
3029
3030 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003031 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003032 } else {
3033 hci_auth_cfm(conn, ev->status);
3034
3035 hci_conn_hold(conn);
3036 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003037 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003038 }
3039
3040unlock:
3041 hci_dev_unlock(hdev);
3042}
3043
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003044static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003045{
3046 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003047 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3048 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003049 /* If both remote and local IO capabilities allow MITM
3050 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003051 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3052 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3053 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003054 else
Mikel Astizacabae92013-06-28 10:56:28 +02003055 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003056 }
3057
3058 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003059 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3060 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003061 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003062
3063 return conn->auth_type;
3064}
3065
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003066static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003067{
3068 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3069 struct hci_conn *conn;
3070
3071 BT_DBG("%s", hdev->name);
3072
3073 hci_dev_lock(hdev);
3074
3075 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003076 if (!conn)
3077 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003078
Johan Hedberg03b555e2011-01-04 15:40:05 +02003079 hci_conn_hold(conn);
3080
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003081 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003082 goto unlock;
3083
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003084 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003085 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003086 struct hci_cp_io_capability_reply cp;
3087
3088 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303089 /* Change the IO capability from KeyboardDisplay
3090 * to DisplayYesNo as it is not supported by BT spec. */
3091 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003092 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003093 conn->auth_type = hci_get_auth_req(conn);
3094 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003095
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003096 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3097 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003098 cp.oob_data = 0x01;
3099 else
3100 cp.oob_data = 0x00;
3101
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003102 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003103 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003104 } else {
3105 struct hci_cp_io_capability_neg_reply cp;
3106
3107 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003108 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003109
3110 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003111 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003112 }
3113
3114unlock:
3115 hci_dev_unlock(hdev);
3116}
3117
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003118static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003119{
3120 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3121 struct hci_conn *conn;
3122
3123 BT_DBG("%s", hdev->name);
3124
3125 hci_dev_lock(hdev);
3126
3127 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3128 if (!conn)
3129 goto unlock;
3130
Johan Hedberg03b555e2011-01-04 15:40:05 +02003131 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003132 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003133 if (ev->oob_data)
3134 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003135
3136unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003137 hci_dev_unlock(hdev);
3138}
3139
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003140static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3141 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003142{
3143 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003144 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003145 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003146
3147 BT_DBG("%s", hdev->name);
3148
3149 hci_dev_lock(hdev);
3150
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003151 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003152 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003153
Johan Hedberg7a828902011-04-28 11:28:53 -07003154 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3155 if (!conn)
3156 goto unlock;
3157
3158 loc_mitm = (conn->auth_type & 0x01);
3159 rem_mitm = (conn->remote_auth & 0x01);
3160
3161 /* If we require MITM but the remote device can't provide that
3162 * (it has NoInputNoOutput) then reject the confirmation
3163 * request. The only exception is when we're dedicated bonding
3164 * initiators (connect_cfm_cb set) since then we always have the MITM
3165 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003166 if (!conn->connect_cfm_cb && loc_mitm &&
3167 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003168 BT_DBG("Rejecting request: remote device can't provide MITM");
3169 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003170 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003171 goto unlock;
3172 }
3173
3174 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003175 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3176 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003177
3178 /* If we're not the initiators request authorization to
3179 * proceed from user space (mgmt_user_confirm with
3180 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003181 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003182 BT_DBG("Confirming auto-accept as acceptor");
3183 confirm_hint = 1;
3184 goto confirm;
3185 }
3186
Johan Hedberg9f616562011-04-28 11:28:54 -07003187 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003188 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003189
3190 if (hdev->auto_accept_delay > 0) {
3191 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
Johan Hedberg7bc18d92013-10-16 18:11:39 +03003192 queue_delayed_work(conn->hdev->workqueue,
3193 &conn->auto_accept_work, delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003194 goto unlock;
3195 }
3196
Johan Hedberg7a828902011-04-28 11:28:53 -07003197 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003198 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003199 goto unlock;
3200 }
3201
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003202confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003203 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003204 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003205
3206unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003207 hci_dev_unlock(hdev);
3208}
3209
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003210static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3211 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003212{
3213 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3214
3215 BT_DBG("%s", hdev->name);
3216
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003217 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003218 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003219}
3220
Johan Hedberg92a25252012-09-06 18:39:26 +03003221static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3222 struct sk_buff *skb)
3223{
3224 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3225 struct hci_conn *conn;
3226
3227 BT_DBG("%s", hdev->name);
3228
3229 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3230 if (!conn)
3231 return;
3232
3233 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3234 conn->passkey_entered = 0;
3235
3236 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3237 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3238 conn->dst_type, conn->passkey_notify,
3239 conn->passkey_entered);
3240}
3241
3242static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3243{
3244 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3245 struct hci_conn *conn;
3246
3247 BT_DBG("%s", hdev->name);
3248
3249 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3250 if (!conn)
3251 return;
3252
3253 switch (ev->type) {
3254 case HCI_KEYPRESS_STARTED:
3255 conn->passkey_entered = 0;
3256 return;
3257
3258 case HCI_KEYPRESS_ENTERED:
3259 conn->passkey_entered++;
3260 break;
3261
3262 case HCI_KEYPRESS_ERASED:
3263 conn->passkey_entered--;
3264 break;
3265
3266 case HCI_KEYPRESS_CLEARED:
3267 conn->passkey_entered = 0;
3268 break;
3269
3270 case HCI_KEYPRESS_COMPLETED:
3271 return;
3272 }
3273
3274 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3275 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3276 conn->dst_type, conn->passkey_notify,
3277 conn->passkey_entered);
3278}
3279
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003280static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3281 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003282{
3283 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3284 struct hci_conn *conn;
3285
3286 BT_DBG("%s", hdev->name);
3287
3288 hci_dev_lock(hdev);
3289
3290 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003291 if (!conn)
3292 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003293
Johan Hedberg2a611692011-02-19 12:06:00 -03003294 /* To avoid duplicate auth_failed events to user space we check
3295 * the HCI_CONN_AUTH_PEND flag which will be set if we
3296 * initiated the authentication. A traditional auth_complete
3297 * event gets always produced as initiator and is also mapped to
3298 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003299 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003300 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003301 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003302
David Herrmann76a68ba2013-04-06 20:28:37 +02003303 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003304
3305unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003306 hci_dev_unlock(hdev);
3307}
3308
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003309static void hci_remote_host_features_evt(struct hci_dev *hdev,
3310 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003311{
3312 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3313 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003314 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003315
3316 BT_DBG("%s", hdev->name);
3317
3318 hci_dev_lock(hdev);
3319
Johan Hedbergcad718e2013-04-17 15:00:51 +03003320 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3321 if (conn)
3322 memcpy(conn->features[1], ev->features, 8);
3323
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003324 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3325 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003326 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003327
3328 hci_dev_unlock(hdev);
3329}
3330
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003331static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3332 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003333{
3334 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3335 struct oob_data *data;
3336
3337 BT_DBG("%s", hdev->name);
3338
3339 hci_dev_lock(hdev);
3340
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003341 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003342 goto unlock;
3343
Szymon Janc2763eda2011-03-22 13:12:22 +01003344 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3345 if (data) {
3346 struct hci_cp_remote_oob_data_reply cp;
3347
3348 bacpy(&cp.bdaddr, &ev->bdaddr);
3349 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3350 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3351
3352 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003353 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003354 } else {
3355 struct hci_cp_remote_oob_data_neg_reply cp;
3356
3357 bacpy(&cp.bdaddr, &ev->bdaddr);
3358 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003359 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003360 }
3361
Szymon Jance1ba1f12011-04-06 13:01:59 +02003362unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003363 hci_dev_unlock(hdev);
3364}
3365
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003366static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3367 struct sk_buff *skb)
3368{
3369 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3370 struct hci_conn *hcon, *bredr_hcon;
3371
3372 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3373 ev->status);
3374
3375 hci_dev_lock(hdev);
3376
3377 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3378 if (!hcon) {
3379 hci_dev_unlock(hdev);
3380 return;
3381 }
3382
3383 if (ev->status) {
3384 hci_conn_del(hcon);
3385 hci_dev_unlock(hdev);
3386 return;
3387 }
3388
3389 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3390
3391 hcon->state = BT_CONNECTED;
3392 bacpy(&hcon->dst, &bredr_hcon->dst);
3393
3394 hci_conn_hold(hcon);
3395 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003396 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003397
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003398 hci_conn_add_sysfs(hcon);
3399
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003400 amp_physical_cfm(bredr_hcon, hcon);
3401
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003402 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003403}
3404
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003405static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3406{
3407 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3408 struct hci_conn *hcon;
3409 struct hci_chan *hchan;
3410 struct amp_mgr *mgr;
3411
3412 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3413 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3414 ev->status);
3415
3416 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3417 if (!hcon)
3418 return;
3419
3420 /* Create AMP hchan */
3421 hchan = hci_chan_create(hcon);
3422 if (!hchan)
3423 return;
3424
3425 hchan->handle = le16_to_cpu(ev->handle);
3426
3427 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3428
3429 mgr = hcon->amp_mgr;
3430 if (mgr && mgr->bredr_chan) {
3431 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3432
3433 l2cap_chan_lock(bredr_chan);
3434
3435 bredr_chan->conn->mtu = hdev->block_mtu;
3436 l2cap_logical_cfm(bredr_chan, hchan, 0);
3437 hci_conn_hold(hcon);
3438
3439 l2cap_chan_unlock(bredr_chan);
3440 }
3441}
3442
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003443static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3444 struct sk_buff *skb)
3445{
3446 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3447 struct hci_chan *hchan;
3448
3449 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3450 le16_to_cpu(ev->handle), ev->status);
3451
3452 if (ev->status)
3453 return;
3454
3455 hci_dev_lock(hdev);
3456
3457 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3458 if (!hchan)
3459 goto unlock;
3460
3461 amp_destroy_logical_link(hchan, ev->reason);
3462
3463unlock:
3464 hci_dev_unlock(hdev);
3465}
3466
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003467static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3468 struct sk_buff *skb)
3469{
3470 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3471 struct hci_conn *hcon;
3472
3473 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3474
3475 if (ev->status)
3476 return;
3477
3478 hci_dev_lock(hdev);
3479
3480 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3481 if (hcon) {
3482 hcon->state = BT_CLOSED;
3483 hci_conn_del(hcon);
3484 }
3485
3486 hci_dev_unlock(hdev);
3487}
3488
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003489static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003490{
3491 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3492 struct hci_conn *conn;
3493
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003494 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003495
3496 hci_dev_lock(hdev);
3497
Andre Guedesb47a09b2012-07-27 15:10:15 -03003498 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003499 if (!conn) {
3500 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3501 if (!conn) {
3502 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003503 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003504 }
Andre Guedes29b79882011-05-31 14:20:54 -03003505
3506 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003507
Marcel Holtmann880be4e2013-10-13 07:25:18 -07003508 /* The advertising parameters for own address type
3509 * define which source address and source address
3510 * type this connections has.
3511 */
3512 if (bacmp(&conn->src, BDADDR_ANY)) {
3513 conn->src_type = ADDR_LE_DEV_PUBLIC;
3514 } else {
3515 bacpy(&conn->src, &hdev->static_addr);
3516 conn->src_type = ADDR_LE_DEV_RANDOM;
3517 }
3518
Andre Guedesb9b343d2012-07-27 15:10:11 -03003519 if (ev->role == LE_CONN_ROLE_MASTER) {
3520 conn->out = true;
3521 conn->link_mode |= HCI_LM_MASTER;
3522 }
Ville Tervob62f3282011-02-10 22:38:50 -03003523 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003524
Andre Guedescd17dec2012-07-27 15:10:16 -03003525 if (ev->status) {
3526 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3527 conn->dst_type, ev->status);
3528 hci_proto_connect_cfm(conn, ev->status);
3529 conn->state = BT_CLOSED;
3530 hci_conn_del(conn);
3531 goto unlock;
3532 }
3533
Johan Hedbergb644ba32012-01-17 21:48:47 +02003534 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3535 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003536 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003537
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003538 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003539 conn->handle = __le16_to_cpu(ev->handle);
3540 conn->state = BT_CONNECTED;
3541
Ville Tervofcd89c02011-02-10 22:38:47 -03003542 hci_conn_add_sysfs(conn);
3543
3544 hci_proto_connect_cfm(conn, ev->status);
3545
3546unlock:
3547 hci_dev_unlock(hdev);
3548}
3549
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003550static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003551{
Andre Guedese95beb42011-09-26 20:48:35 -03003552 u8 num_reports = skb->data[0];
3553 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003554 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003555
Andre Guedese95beb42011-09-26 20:48:35 -03003556 while (num_reports--) {
3557 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003558
Andre Guedes3c9e9192012-01-10 18:20:50 -03003559 rssi = ev->data[ev->length];
3560 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003561 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003562
Andre Guedese95beb42011-09-26 20:48:35 -03003563 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003564 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003565}
3566
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003567static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003568{
3569 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3570 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003571 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003572 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003573 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003574
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003575 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003576
3577 hci_dev_lock(hdev);
3578
3579 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003580 if (conn == NULL)
3581 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003582
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003583 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3584 if (ltk == NULL)
3585 goto not_found;
3586
3587 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003588 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003589
3590 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03003591 conn->pending_sec_level = BT_SECURITY_HIGH;
3592 else
3593 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003594
Andre Guedes89cbb4d2013-07-31 16:25:29 -03003595 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003596
3597 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3598
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003599 if (ltk->type & HCI_SMP_STK) {
3600 list_del(&ltk->list);
3601 kfree(ltk);
3602 }
3603
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003604 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003605
3606 return;
3607
3608not_found:
3609 neg.handle = ev->handle;
3610 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3611 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003612}
3613
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003614static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003615{
3616 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3617
3618 skb_pull(skb, sizeof(*le_ev));
3619
3620 switch (le_ev->subevent) {
3621 case HCI_EV_LE_CONN_COMPLETE:
3622 hci_le_conn_complete_evt(hdev, skb);
3623 break;
3624
Andre Guedes9aa04c92011-05-26 16:23:51 -03003625 case HCI_EV_LE_ADVERTISING_REPORT:
3626 hci_le_adv_report_evt(hdev, skb);
3627 break;
3628
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003629 case HCI_EV_LE_LTK_REQ:
3630 hci_le_ltk_request_evt(hdev, skb);
3631 break;
3632
Ville Tervofcd89c02011-02-10 22:38:47 -03003633 default:
3634 break;
3635 }
3636}
3637
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003638static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3639{
3640 struct hci_ev_channel_selected *ev = (void *) skb->data;
3641 struct hci_conn *hcon;
3642
3643 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3644
3645 skb_pull(skb, sizeof(*ev));
3646
3647 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3648 if (!hcon)
3649 return;
3650
3651 amp_read_loc_assoc_final_data(hdev, hcon);
3652}
3653
Linus Torvalds1da177e2005-04-16 15:20:36 -07003654void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3655{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003656 struct hci_event_hdr *hdr = (void *) skb->data;
3657 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003658
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003659 hci_dev_lock(hdev);
3660
3661 /* Received events are (currently) only needed when a request is
3662 * ongoing so avoid unnecessary memory allocation.
3663 */
3664 if (hdev->req_status == HCI_REQ_PEND) {
3665 kfree_skb(hdev->recv_evt);
3666 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3667 }
3668
3669 hci_dev_unlock(hdev);
3670
Linus Torvalds1da177e2005-04-16 15:20:36 -07003671 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3672
Johan Hedberg02350a72013-04-03 21:50:29 +03003673 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02003674 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
3675 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03003676
3677 hci_req_cmd_complete(hdev, opcode, 0);
3678 }
3679
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003680 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003681 case HCI_EV_INQUIRY_COMPLETE:
3682 hci_inquiry_complete_evt(hdev, skb);
3683 break;
3684
3685 case HCI_EV_INQUIRY_RESULT:
3686 hci_inquiry_result_evt(hdev, skb);
3687 break;
3688
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003689 case HCI_EV_CONN_COMPLETE:
3690 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003691 break;
3692
Linus Torvalds1da177e2005-04-16 15:20:36 -07003693 case HCI_EV_CONN_REQUEST:
3694 hci_conn_request_evt(hdev, skb);
3695 break;
3696
Linus Torvalds1da177e2005-04-16 15:20:36 -07003697 case HCI_EV_DISCONN_COMPLETE:
3698 hci_disconn_complete_evt(hdev, skb);
3699 break;
3700
Linus Torvalds1da177e2005-04-16 15:20:36 -07003701 case HCI_EV_AUTH_COMPLETE:
3702 hci_auth_complete_evt(hdev, skb);
3703 break;
3704
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003705 case HCI_EV_REMOTE_NAME:
3706 hci_remote_name_evt(hdev, skb);
3707 break;
3708
Linus Torvalds1da177e2005-04-16 15:20:36 -07003709 case HCI_EV_ENCRYPT_CHANGE:
3710 hci_encrypt_change_evt(hdev, skb);
3711 break;
3712
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003713 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3714 hci_change_link_key_complete_evt(hdev, skb);
3715 break;
3716
3717 case HCI_EV_REMOTE_FEATURES:
3718 hci_remote_features_evt(hdev, skb);
3719 break;
3720
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003721 case HCI_EV_CMD_COMPLETE:
3722 hci_cmd_complete_evt(hdev, skb);
3723 break;
3724
3725 case HCI_EV_CMD_STATUS:
3726 hci_cmd_status_evt(hdev, skb);
3727 break;
3728
3729 case HCI_EV_ROLE_CHANGE:
3730 hci_role_change_evt(hdev, skb);
3731 break;
3732
3733 case HCI_EV_NUM_COMP_PKTS:
3734 hci_num_comp_pkts_evt(hdev, skb);
3735 break;
3736
3737 case HCI_EV_MODE_CHANGE:
3738 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003739 break;
3740
3741 case HCI_EV_PIN_CODE_REQ:
3742 hci_pin_code_request_evt(hdev, skb);
3743 break;
3744
3745 case HCI_EV_LINK_KEY_REQ:
3746 hci_link_key_request_evt(hdev, skb);
3747 break;
3748
3749 case HCI_EV_LINK_KEY_NOTIFY:
3750 hci_link_key_notify_evt(hdev, skb);
3751 break;
3752
3753 case HCI_EV_CLOCK_OFFSET:
3754 hci_clock_offset_evt(hdev, skb);
3755 break;
3756
Marcel Holtmanna8746412008-07-14 20:13:46 +02003757 case HCI_EV_PKT_TYPE_CHANGE:
3758 hci_pkt_type_change_evt(hdev, skb);
3759 break;
3760
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003761 case HCI_EV_PSCAN_REP_MODE:
3762 hci_pscan_rep_mode_evt(hdev, skb);
3763 break;
3764
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003765 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3766 hci_inquiry_result_with_rssi_evt(hdev, skb);
3767 break;
3768
3769 case HCI_EV_REMOTE_EXT_FEATURES:
3770 hci_remote_ext_features_evt(hdev, skb);
3771 break;
3772
3773 case HCI_EV_SYNC_CONN_COMPLETE:
3774 hci_sync_conn_complete_evt(hdev, skb);
3775 break;
3776
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003777 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3778 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003779 break;
3780
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003781 case HCI_EV_KEY_REFRESH_COMPLETE:
3782 hci_key_refresh_complete_evt(hdev, skb);
3783 break;
3784
Marcel Holtmann04936842008-07-14 20:13:48 +02003785 case HCI_EV_IO_CAPA_REQUEST:
3786 hci_io_capa_request_evt(hdev, skb);
3787 break;
3788
Johan Hedberg03b555e2011-01-04 15:40:05 +02003789 case HCI_EV_IO_CAPA_REPLY:
3790 hci_io_capa_reply_evt(hdev, skb);
3791 break;
3792
Johan Hedberga5c29682011-02-19 12:05:57 -03003793 case HCI_EV_USER_CONFIRM_REQUEST:
3794 hci_user_confirm_request_evt(hdev, skb);
3795 break;
3796
Brian Gix1143d452011-11-23 08:28:34 -08003797 case HCI_EV_USER_PASSKEY_REQUEST:
3798 hci_user_passkey_request_evt(hdev, skb);
3799 break;
3800
Johan Hedberg92a25252012-09-06 18:39:26 +03003801 case HCI_EV_USER_PASSKEY_NOTIFY:
3802 hci_user_passkey_notify_evt(hdev, skb);
3803 break;
3804
3805 case HCI_EV_KEYPRESS_NOTIFY:
3806 hci_keypress_notify_evt(hdev, skb);
3807 break;
3808
Marcel Holtmann04936842008-07-14 20:13:48 +02003809 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3810 hci_simple_pair_complete_evt(hdev, skb);
3811 break;
3812
Marcel Holtmann41a96212008-07-14 20:13:48 +02003813 case HCI_EV_REMOTE_HOST_FEATURES:
3814 hci_remote_host_features_evt(hdev, skb);
3815 break;
3816
Ville Tervofcd89c02011-02-10 22:38:47 -03003817 case HCI_EV_LE_META:
3818 hci_le_meta_evt(hdev, skb);
3819 break;
3820
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003821 case HCI_EV_CHANNEL_SELECTED:
3822 hci_chan_selected_evt(hdev, skb);
3823 break;
3824
Szymon Janc2763eda2011-03-22 13:12:22 +01003825 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3826 hci_remote_oob_data_request_evt(hdev, skb);
3827 break;
3828
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003829 case HCI_EV_PHY_LINK_COMPLETE:
3830 hci_phy_link_complete_evt(hdev, skb);
3831 break;
3832
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003833 case HCI_EV_LOGICAL_LINK_COMPLETE:
3834 hci_loglink_complete_evt(hdev, skb);
3835 break;
3836
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003837 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3838 hci_disconn_loglink_complete_evt(hdev, skb);
3839 break;
3840
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003841 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3842 hci_disconn_phylink_complete_evt(hdev, skb);
3843 break;
3844
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003845 case HCI_EV_NUM_COMP_BLOCKS:
3846 hci_num_comp_blocks_evt(hdev, skb);
3847 break;
3848
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003849 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003850 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003851 break;
3852 }
3853
3854 kfree_skb(skb);
3855 hdev->stat.evt_rx++;
3856}