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