blob: 7b133f0e0c3cb92d198668e49e733eb8fed76cee [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 Holtmanna9de9242007-10-20 13:33:56 +0200198}
199
200static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
201{
202 __u8 status = *((__u8 *) skb->data);
203 void *sent;
204
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300205 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200206
207 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
208 if (!sent)
209 return;
210
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200211 hci_dev_lock(hdev);
212
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200213 if (test_bit(HCI_MGMT, &hdev->dev_flags))
214 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200215 else if (!status)
216 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200217
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200218 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200219}
220
221static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
222{
223 struct hci_rp_read_local_name *rp = (void *) skb->data;
224
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300225 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200226
227 if (rp->status)
228 return;
229
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200230 if (test_bit(HCI_SETUP, &hdev->dev_flags))
231 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200232}
233
234static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
235{
236 __u8 status = *((__u8 *) skb->data);
237 void *sent;
238
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300239 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200240
241 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
242 if (!sent)
243 return;
244
245 if (!status) {
246 __u8 param = *((__u8 *) sent);
247
248 if (param == AUTH_ENABLED)
249 set_bit(HCI_AUTH, &hdev->flags);
250 else
251 clear_bit(HCI_AUTH, &hdev->flags);
252 }
253
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200254 if (test_bit(HCI_MGMT, &hdev->dev_flags))
255 mgmt_auth_enable_complete(hdev, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200256}
257
258static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
259{
260 __u8 status = *((__u8 *) skb->data);
261 void *sent;
262
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300263 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200264
265 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
266 if (!sent)
267 return;
268
269 if (!status) {
270 __u8 param = *((__u8 *) sent);
271
272 if (param)
273 set_bit(HCI_ENCRYPT, &hdev->flags);
274 else
275 clear_bit(HCI_ENCRYPT, &hdev->flags);
276 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200277}
278
279static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
280{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200281 __u8 param, status = *((__u8 *) skb->data);
282 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200283 void *sent;
284
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300285 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200286
287 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
288 if (!sent)
289 return;
290
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200291 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200292
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200293 hci_dev_lock(hdev);
294
Mikel Astizfa1bd912012-08-09 09:52:29 +0200295 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200296 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200297 hdev->discov_timeout = 0;
298 goto done;
299 }
300
Johan Hedberg0663ca22013-10-02 13:43:14 +0300301 /* We need to ensure that we set this back on if someone changed
302 * the scan mode through a raw HCI socket.
303 */
304 set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
305
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200306 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
307 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200308
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200309 if (param & SCAN_INQUIRY) {
310 set_bit(HCI_ISCAN, &hdev->flags);
311 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200312 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200313 if (hdev->discov_timeout > 0) {
314 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
315 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300316 to);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200317 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200318 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200319 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200320
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200321 if (param & SCAN_PAGE) {
322 set_bit(HCI_PSCAN, &hdev->flags);
323 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200324 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200325 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200326 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200327
328done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200329 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200330}
331
332static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
333{
334 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
335
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300336 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200337
338 if (rp->status)
339 return;
340
341 memcpy(hdev->dev_class, rp->dev_class, 3);
342
343 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300344 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200345}
346
347static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
348{
349 __u8 status = *((__u8 *) skb->data);
350 void *sent;
351
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300352 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200353
354 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
355 if (!sent)
356 return;
357
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100358 hci_dev_lock(hdev);
359
360 if (status == 0)
361 memcpy(hdev->dev_class, sent, 3);
362
363 if (test_bit(HCI_MGMT, &hdev->dev_flags))
364 mgmt_set_class_of_dev_complete(hdev, sent, status);
365
366 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200367}
368
369static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
370{
371 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200373
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300374 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200375
376 if (rp->status)
377 return;
378
379 setting = __le16_to_cpu(rp->voice_setting);
380
Marcel Holtmannf383f272008-07-14 20:13:47 +0200381 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200382 return;
383
384 hdev->voice_setting = setting;
385
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300386 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200387
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200388 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200390}
391
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300392static void hci_cc_write_voice_setting(struct hci_dev *hdev,
393 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200394{
395 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200396 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 void *sent;
398
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300399 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
Marcel Holtmannf383f272008-07-14 20:13:47 +0200401 if (status)
402 return;
403
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200404 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
405 if (!sent)
406 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
Marcel Holtmannf383f272008-07-14 20:13:47 +0200408 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410 if (hdev->voice_setting == setting)
411 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
Marcel Holtmannf383f272008-07-14 20:13:47 +0200413 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300415 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200416
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200417 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200418 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419}
420
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -0700421static void hci_cc_read_num_supported_iac(struct hci_dev *hdev,
422 struct sk_buff *skb)
423{
424 struct hci_rp_read_num_supported_iac *rp = (void *) skb->data;
425
426 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
427
428 if (rp->status)
429 return;
430
431 hdev->num_iac = rp->num_iac;
432
433 BT_DBG("%s num iac %d", hdev->name, hdev->num_iac);
434}
435
Marcel Holtmann333140b2008-07-14 20:13:48 +0200436static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
437{
438 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300439 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200440
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300441 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200442
Marcel Holtmann333140b2008-07-14 20:13:48 +0200443 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
444 if (!sent)
445 return;
446
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300447 if (!status) {
448 if (sent->mode)
Johan Hedbergcad718e2013-04-17 15:00:51 +0300449 hdev->features[1][0] |= LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300450 else
Johan Hedbergcad718e2013-04-17 15:00:51 +0300451 hdev->features[1][0] &= ~LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300452 }
453
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200454 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300455 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200456 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300457 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200458 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
459 else
460 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
461 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200462}
463
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200464static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
465{
466 struct hci_rp_read_local_version *rp = (void *) skb->data;
467
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300468 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200469
470 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200471 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200472
473 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200474 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200475 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200476 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200477 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200478
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300479 BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300480 hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200481}
482
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300483static void hci_cc_read_local_commands(struct hci_dev *hdev,
484 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200485{
486 struct hci_rp_read_local_commands *rp = (void *) skb->data;
487
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300488 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200489
Johan Hedberg2177bab2013-03-05 20:37:43 +0200490 if (!rp->status)
491 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200492}
493
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300494static void hci_cc_read_local_features(struct hci_dev *hdev,
495 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200496{
497 struct hci_rp_read_local_features *rp = (void *) skb->data;
498
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300499 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200500
501 if (rp->status)
502 return;
503
504 memcpy(hdev->features, rp->features, 8);
505
506 /* Adjust default settings according to features
507 * supported by device. */
508
Johan Hedbergcad718e2013-04-17 15:00:51 +0300509 if (hdev->features[0][0] & LMP_3SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200510 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
511
Johan Hedbergcad718e2013-04-17 15:00:51 +0300512 if (hdev->features[0][0] & LMP_5SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200513 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
514
Johan Hedbergcad718e2013-04-17 15:00:51 +0300515 if (hdev->features[0][1] & LMP_HV2) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200516 hdev->pkt_type |= (HCI_HV2);
517 hdev->esco_type |= (ESCO_HV2);
518 }
519
Johan Hedbergcad718e2013-04-17 15:00:51 +0300520 if (hdev->features[0][1] & LMP_HV3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200521 hdev->pkt_type |= (HCI_HV3);
522 hdev->esco_type |= (ESCO_HV3);
523 }
524
Andre Guedes45db810f2012-07-24 15:03:49 -0300525 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200526 hdev->esco_type |= (ESCO_EV3);
527
Johan Hedbergcad718e2013-04-17 15:00:51 +0300528 if (hdev->features[0][4] & LMP_EV4)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200529 hdev->esco_type |= (ESCO_EV4);
530
Johan Hedbergcad718e2013-04-17 15:00:51 +0300531 if (hdev->features[0][4] & LMP_EV5)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200532 hdev->esco_type |= (ESCO_EV5);
533
Johan Hedbergcad718e2013-04-17 15:00:51 +0300534 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100535 hdev->esco_type |= (ESCO_2EV3);
536
Johan Hedbergcad718e2013-04-17 15:00:51 +0300537 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100538 hdev->esco_type |= (ESCO_3EV3);
539
Johan Hedbergcad718e2013-04-17 15:00:51 +0300540 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100541 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
542
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200543 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
Johan Hedbergcad718e2013-04-17 15:00:51 +0300544 hdev->features[0][0], hdev->features[0][1],
545 hdev->features[0][2], hdev->features[0][3],
546 hdev->features[0][4], hdev->features[0][5],
547 hdev->features[0][6], hdev->features[0][7]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200548}
549
Andre Guedes971e3a42011-06-30 19:20:52 -0300550static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300551 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300552{
553 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
554
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300555 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300556
557 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200558 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300559
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300560 hdev->max_page = rp->max_page;
561
Johan Hedbergcad718e2013-04-17 15:00:51 +0300562 if (rp->page < HCI_MAX_PAGES)
563 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300564}
565
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200566static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300567 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200568{
569 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
570
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300571 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200572
Johan Hedberg42c6b122013-03-05 20:37:49 +0200573 if (!rp->status)
574 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200575}
576
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200577static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
578{
579 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
580
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300581 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200582
583 if (rp->status)
584 return;
585
586 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
587 hdev->sco_mtu = rp->sco_mtu;
588 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
589 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
590
591 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
592 hdev->sco_mtu = 64;
593 hdev->sco_pkts = 8;
594 }
595
596 hdev->acl_cnt = hdev->acl_pkts;
597 hdev->sco_cnt = hdev->sco_pkts;
598
Gustavo Padovan807deac2012-05-17 00:36:24 -0300599 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
600 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200601}
602
603static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
604{
605 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
606
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300607 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200608
609 if (!rp->status)
610 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200611}
612
Johan Hedbergf332ec62013-03-15 17:07:11 -0500613static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
614 struct sk_buff *skb)
615{
616 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
617
618 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
619
620 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
621 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
622 hdev->page_scan_window = __le16_to_cpu(rp->window);
623 }
624}
625
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500626static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
627 struct sk_buff *skb)
628{
629 u8 status = *((u8 *) skb->data);
630 struct hci_cp_write_page_scan_activity *sent;
631
632 BT_DBG("%s status 0x%2.2x", hdev->name, status);
633
634 if (status)
635 return;
636
637 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
638 if (!sent)
639 return;
640
641 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
642 hdev->page_scan_window = __le16_to_cpu(sent->window);
643}
644
Johan Hedbergf332ec62013-03-15 17:07:11 -0500645static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
646 struct sk_buff *skb)
647{
648 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
649
650 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
651
652 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
653 hdev->page_scan_type = rp->type;
654}
655
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500656static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
657 struct sk_buff *skb)
658{
659 u8 status = *((u8 *) skb->data);
660 u8 *type;
661
662 BT_DBG("%s status 0x%2.2x", hdev->name, status);
663
664 if (status)
665 return;
666
667 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
668 if (type)
669 hdev->page_scan_type = *type;
670}
671
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200672static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300673 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200674{
675 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
676
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300677 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200678
679 if (rp->status)
680 return;
681
682 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
683 hdev->block_len = __le16_to_cpu(rp->block_len);
684 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
685
686 hdev->block_cnt = hdev->num_blocks;
687
688 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300689 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200690}
691
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300692static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300693 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300694{
695 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
696
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300697 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300698
699 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300700 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300701
702 hdev->amp_status = rp->amp_status;
703 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
704 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
705 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
706 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
707 hdev->amp_type = rp->amp_type;
708 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
709 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
710 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
711 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
712
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300713a2mp_rsp:
714 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300715}
716
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300717static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
718 struct sk_buff *skb)
719{
720 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
721 struct amp_assoc *assoc = &hdev->loc_assoc;
722 size_t rem_len, frag_len;
723
724 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
725
726 if (rp->status)
727 goto a2mp_rsp;
728
729 frag_len = skb->len - sizeof(*rp);
730 rem_len = __le16_to_cpu(rp->rem_len);
731
732 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300733 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300734
735 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
736 assoc->offset += frag_len;
737
738 /* Read other fragments */
739 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
740
741 return;
742 }
743
744 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
745 assoc->len = assoc->offset + rem_len;
746 assoc->offset = 0;
747
748a2mp_rsp:
749 /* Send A2MP Rsp when all fragments are received */
750 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300751 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300752}
753
Johan Hedbergd5859e22011-01-25 01:19:58 +0200754static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300755 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200756{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700757 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200758
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300759 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200760
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700761 if (!rp->status)
762 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200763}
764
Johan Hedberg980e1a52011-01-22 06:10:07 +0200765static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
766{
767 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
768 struct hci_cp_pin_code_reply *cp;
769 struct hci_conn *conn;
770
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300771 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200772
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200773 hci_dev_lock(hdev);
774
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200775 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200776 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200777
Mikel Astizfa1bd912012-08-09 09:52:29 +0200778 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200779 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200780
781 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
782 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200783 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200784
785 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
786 if (conn)
787 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200788
789unlock:
790 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200791}
792
793static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
794{
795 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
796
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300797 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200798
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200799 hci_dev_lock(hdev);
800
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200801 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200802 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300803 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200804
805 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200806}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200807
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300808static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
809 struct sk_buff *skb)
810{
811 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
812
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300813 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300814
815 if (rp->status)
816 return;
817
818 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
819 hdev->le_pkts = rp->le_max_pkt;
820
821 hdev->le_cnt = hdev->le_pkts;
822
823 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300824}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200825
Johan Hedberg60e77322013-01-22 14:01:59 +0200826static void hci_cc_le_read_local_features(struct hci_dev *hdev,
827 struct sk_buff *skb)
828{
829 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
830
831 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
832
833 if (!rp->status)
834 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200835}
836
Johan Hedberg8fa19092012-10-19 20:57:49 +0300837static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
838 struct sk_buff *skb)
839{
840 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
841
842 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
843
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500844 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300845 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300846}
847
Johan Hedberga5c29682011-02-19 12:05:57 -0300848static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
849{
850 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
851
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300852 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300853
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200854 hci_dev_lock(hdev);
855
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200856 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300857 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
858 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200859
860 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300861}
862
863static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300864 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300865{
866 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
867
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300868 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300869
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200870 hci_dev_lock(hdev);
871
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200872 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200873 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300874 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200875
876 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300877}
878
Brian Gix1143d452011-11-23 08:28:34 -0800879static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
880{
881 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
882
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300883 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800884
885 hci_dev_lock(hdev);
886
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200887 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200888 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300889 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800890
891 hci_dev_unlock(hdev);
892}
893
894static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300895 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800896{
897 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
898
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300899 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800900
901 hci_dev_lock(hdev);
902
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200903 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800904 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300905 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800906
907 hci_dev_unlock(hdev);
908}
909
Szymon Jancc35938b2011-03-22 13:12:21 +0100910static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300911 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100912{
913 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
914
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300915 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100916
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200917 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +0200918 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +0100919 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200920 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100921}
922
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100923static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
924{
925 __u8 *sent, status = *((__u8 *) skb->data);
926
927 BT_DBG("%s status 0x%2.2x", hdev->name, status);
928
929 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
930 if (!sent)
931 return;
932
933 hci_dev_lock(hdev);
934
935 if (!status) {
936 if (*sent)
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200937 set_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100938 else
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200939 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100940 }
941
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500942 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100943}
944
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300945static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300946 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300947{
948 struct hci_cp_le_set_scan_enable *cp;
949 __u8 status = *((__u8 *) skb->data);
950
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300951 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300952
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300953 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
954 if (!cp)
955 return;
956
Andre Guedes3fd319b2013-04-30 15:29:36 -0300957 if (status)
958 return;
959
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200960 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -0300961 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300962 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200963 break;
964
Andre Guedes76a388b2013-04-04 20:21:02 -0300965 case LE_SCAN_DISABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300966 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200967 break;
968
969 default:
970 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
971 break;
Andre Guedes35815082011-05-26 16:23:53 -0300972 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300973}
974
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200975static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
976 struct sk_buff *skb)
977{
978 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
979
980 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
981
982 if (!rp->status)
983 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200984}
985
Johan Hedberg9b008c02013-01-22 14:02:01 +0200986static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
987 struct sk_buff *skb)
988{
989 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
990
991 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
992
993 if (!rp->status)
994 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +0200995}
996
Gustavo Padovan6039aa732012-05-23 04:04:18 -0300997static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
998 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -0300999{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001000 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001001 __u8 status = *((__u8 *) skb->data);
1002
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001003 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001004
Johan Hedberg06199cf2012-02-22 16:37:11 +02001005 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001006 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001007 return;
1008
Johan Hedberg8f984df2012-02-28 01:07:22 +02001009 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001010 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001011 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001012 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1013 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001014 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001015 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001016 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001017 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001018
1019 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001020 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001021 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001022 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001023 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001024}
1025
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001026static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1027 struct sk_buff *skb)
1028{
1029 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1030
1031 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1032 hdev->name, rp->status, rp->phy_handle);
1033
1034 if (rp->status)
1035 return;
1036
1037 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1038}
1039
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001040static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001041{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001042 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001043
1044 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001045 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001046 return;
1047 }
1048
Andre Guedes89352e72011-11-04 14:16:53 -03001049 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001050}
1051
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001052static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001054 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001057 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001058
1059 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 if (!cp)
1061 return;
1062
1063 hci_dev_lock(hdev);
1064
1065 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1066
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001067 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068
1069 if (status) {
1070 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001071 if (status != 0x0c || conn->attempt > 2) {
1072 conn->state = BT_CLOSED;
1073 hci_proto_connect_cfm(conn, status);
1074 hci_conn_del(conn);
1075 } else
1076 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 }
1078 } else {
1079 if (!conn) {
1080 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1081 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001082 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083 conn->link_mode |= HCI_LM_MASTER;
1084 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001085 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086 }
1087 }
1088
1089 hci_dev_unlock(hdev);
1090}
1091
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001092static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001094 struct hci_cp_add_sco *cp;
1095 struct hci_conn *acl, *sco;
1096 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001098 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001099
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001100 if (!status)
1101 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001103 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1104 if (!cp)
1105 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001107 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001109 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001110
1111 hci_dev_lock(hdev);
1112
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001113 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001114 if (acl) {
1115 sco = acl->link;
1116 if (sco) {
1117 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001118
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001119 hci_proto_connect_cfm(sco, status);
1120 hci_conn_del(sco);
1121 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001122 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001123
1124 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125}
1126
Marcel Holtmannf8558552008-07-14 20:13:49 +02001127static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1128{
1129 struct hci_cp_auth_requested *cp;
1130 struct hci_conn *conn;
1131
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001132 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001133
1134 if (!status)
1135 return;
1136
1137 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1138 if (!cp)
1139 return;
1140
1141 hci_dev_lock(hdev);
1142
1143 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1144 if (conn) {
1145 if (conn->state == BT_CONFIG) {
1146 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001147 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001148 }
1149 }
1150
1151 hci_dev_unlock(hdev);
1152}
1153
1154static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1155{
1156 struct hci_cp_set_conn_encrypt *cp;
1157 struct hci_conn *conn;
1158
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001159 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001160
1161 if (!status)
1162 return;
1163
1164 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1165 if (!cp)
1166 return;
1167
1168 hci_dev_lock(hdev);
1169
1170 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1171 if (conn) {
1172 if (conn->state == BT_CONFIG) {
1173 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001174 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001175 }
1176 }
1177
1178 hci_dev_unlock(hdev);
1179}
1180
Johan Hedberg127178d2010-11-18 22:22:29 +02001181static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001182 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001183{
Johan Hedberg392599b2010-11-18 22:22:28 +02001184 if (conn->state != BT_CONFIG || !conn->out)
1185 return 0;
1186
Johan Hedberg765c2a92011-01-19 12:06:52 +05301187 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001188 return 0;
1189
1190 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001191 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001192 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1193 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001194 return 0;
1195
Johan Hedberg392599b2010-11-18 22:22:28 +02001196 return 1;
1197}
1198
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001199static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001200 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001201{
1202 struct hci_cp_remote_name_req cp;
1203
1204 memset(&cp, 0, sizeof(cp));
1205
1206 bacpy(&cp.bdaddr, &e->data.bdaddr);
1207 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1208 cp.pscan_mode = e->data.pscan_mode;
1209 cp.clock_offset = e->data.clock_offset;
1210
1211 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1212}
1213
Johan Hedbergb644ba32012-01-17 21:48:47 +02001214static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001215{
1216 struct discovery_state *discov = &hdev->discovery;
1217 struct inquiry_entry *e;
1218
Johan Hedbergb644ba32012-01-17 21:48:47 +02001219 if (list_empty(&discov->resolve))
1220 return false;
1221
1222 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001223 if (!e)
1224 return false;
1225
Johan Hedbergb644ba32012-01-17 21:48:47 +02001226 if (hci_resolve_name(hdev, e) == 0) {
1227 e->name_state = NAME_PENDING;
1228 return true;
1229 }
1230
1231 return false;
1232}
1233
1234static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001235 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001236{
1237 struct discovery_state *discov = &hdev->discovery;
1238 struct inquiry_entry *e;
1239
1240 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001241 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1242 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001243
1244 if (discov->state == DISCOVERY_STOPPED)
1245 return;
1246
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001247 if (discov->state == DISCOVERY_STOPPING)
1248 goto discov_complete;
1249
1250 if (discov->state != DISCOVERY_RESOLVING)
1251 return;
1252
1253 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001254 /* If the device was not found in a list of found devices names of which
1255 * are pending. there is no need to continue resolving a next name as it
1256 * will be done upon receiving another Remote Name Request Complete
1257 * Event */
1258 if (!e)
1259 return;
1260
1261 list_del(&e->list);
1262 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001263 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001264 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1265 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001266 } else {
1267 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001268 }
1269
Johan Hedbergb644ba32012-01-17 21:48:47 +02001270 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001271 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001272
1273discov_complete:
1274 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1275}
1276
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001277static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1278{
Johan Hedberg127178d2010-11-18 22:22:29 +02001279 struct hci_cp_remote_name_req *cp;
1280 struct hci_conn *conn;
1281
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001282 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001283
1284 /* If successful wait for the name req complete event before
1285 * checking for the need to do authentication */
1286 if (!status)
1287 return;
1288
1289 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1290 if (!cp)
1291 return;
1292
1293 hci_dev_lock(hdev);
1294
1295 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001296
1297 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1298 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1299
Johan Hedberg79c6c702011-04-28 11:28:55 -07001300 if (!conn)
1301 goto unlock;
1302
1303 if (!hci_outgoing_auth_needed(hdev, conn))
1304 goto unlock;
1305
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001306 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001307 struct hci_cp_auth_requested auth_cp;
1308
1309 auth_cp.handle = __cpu_to_le16(conn->handle);
1310 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1311 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001312 }
1313
Johan Hedberg79c6c702011-04-28 11:28:55 -07001314unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001315 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001316}
1317
Marcel Holtmann769be972008-07-14 20:13:49 +02001318static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1319{
1320 struct hci_cp_read_remote_features *cp;
1321 struct hci_conn *conn;
1322
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001323 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001324
1325 if (!status)
1326 return;
1327
1328 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1329 if (!cp)
1330 return;
1331
1332 hci_dev_lock(hdev);
1333
1334 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1335 if (conn) {
1336 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001337 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001338 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001339 }
1340 }
1341
1342 hci_dev_unlock(hdev);
1343}
1344
1345static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1346{
1347 struct hci_cp_read_remote_ext_features *cp;
1348 struct hci_conn *conn;
1349
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001350 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001351
1352 if (!status)
1353 return;
1354
1355 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1356 if (!cp)
1357 return;
1358
1359 hci_dev_lock(hdev);
1360
1361 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1362 if (conn) {
1363 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001364 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001365 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001366 }
1367 }
1368
1369 hci_dev_unlock(hdev);
1370}
1371
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001372static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1373{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001374 struct hci_cp_setup_sync_conn *cp;
1375 struct hci_conn *acl, *sco;
1376 __u16 handle;
1377
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001378 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001379
1380 if (!status)
1381 return;
1382
1383 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1384 if (!cp)
1385 return;
1386
1387 handle = __le16_to_cpu(cp->handle);
1388
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001389 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001390
1391 hci_dev_lock(hdev);
1392
1393 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001394 if (acl) {
1395 sco = acl->link;
1396 if (sco) {
1397 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001398
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001399 hci_proto_connect_cfm(sco, status);
1400 hci_conn_del(sco);
1401 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001402 }
1403
1404 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001405}
1406
1407static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1408{
1409 struct hci_cp_sniff_mode *cp;
1410 struct hci_conn *conn;
1411
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001412 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001413
1414 if (!status)
1415 return;
1416
1417 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1418 if (!cp)
1419 return;
1420
1421 hci_dev_lock(hdev);
1422
1423 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001424 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001425 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001426
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001427 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001428 hci_sco_setup(conn, status);
1429 }
1430
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001431 hci_dev_unlock(hdev);
1432}
1433
1434static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1435{
1436 struct hci_cp_exit_sniff_mode *cp;
1437 struct hci_conn *conn;
1438
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001439 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001440
1441 if (!status)
1442 return;
1443
1444 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1445 if (!cp)
1446 return;
1447
1448 hci_dev_lock(hdev);
1449
1450 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001451 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001452 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001453
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001454 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001455 hci_sco_setup(conn, status);
1456 }
1457
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001458 hci_dev_unlock(hdev);
1459}
1460
Johan Hedberg88c3df12012-02-09 14:27:38 +02001461static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1462{
1463 struct hci_cp_disconnect *cp;
1464 struct hci_conn *conn;
1465
1466 if (!status)
1467 return;
1468
1469 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1470 if (!cp)
1471 return;
1472
1473 hci_dev_lock(hdev);
1474
1475 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1476 if (conn)
1477 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001478 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001479
1480 hci_dev_unlock(hdev);
1481}
1482
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001483static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1484{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001485 struct hci_cp_create_phy_link *cp;
1486
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001487 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001488
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001489 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1490 if (!cp)
1491 return;
1492
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001493 hci_dev_lock(hdev);
1494
1495 if (status) {
1496 struct hci_conn *hcon;
1497
1498 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1499 if (hcon)
1500 hci_conn_del(hcon);
1501 } else {
1502 amp_write_remote_assoc(hdev, cp->phy_handle);
1503 }
1504
1505 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001506}
1507
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001508static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1509{
1510 struct hci_cp_accept_phy_link *cp;
1511
1512 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1513
1514 if (status)
1515 return;
1516
1517 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1518 if (!cp)
1519 return;
1520
1521 amp_write_remote_assoc(hdev, cp->phy_handle);
1522}
1523
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001524static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001525{
1526 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001527 struct discovery_state *discov = &hdev->discovery;
1528 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001529
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001530 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001531
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001532 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001533
1534 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1535 return;
1536
Andre Guedes3e13fa12013-03-27 20:04:56 -03001537 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1538 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1539
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001540 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001541 return;
1542
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001543 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001544
Andre Guedes343f9352012-02-17 20:39:37 -03001545 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001546 goto unlock;
1547
1548 if (list_empty(&discov->resolve)) {
1549 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1550 goto unlock;
1551 }
1552
1553 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1554 if (e && hci_resolve_name(hdev, e) == 0) {
1555 e->name_state = NAME_PENDING;
1556 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1557 } else {
1558 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1559 }
1560
1561unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001562 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001563}
1564
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001565static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001567 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001568 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569 int num_rsp = *((__u8 *) skb->data);
1570
1571 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1572
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001573 if (!num_rsp)
1574 return;
1575
Andre Guedes1519cc12012-03-21 00:03:38 -03001576 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1577 return;
1578
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001580
Johan Hedberge17acd42011-03-30 23:57:16 +03001581 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001582 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001583
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 bacpy(&data.bdaddr, &info->bdaddr);
1585 data.pscan_rep_mode = info->pscan_rep_mode;
1586 data.pscan_period_mode = info->pscan_period_mode;
1587 data.pscan_mode = info->pscan_mode;
1588 memcpy(data.dev_class, info->dev_class, 3);
1589 data.clock_offset = info->clock_offset;
1590 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001591 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001592
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001593 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001594 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001595 info->dev_class, 0, !name_known, ssp, NULL,
1596 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001598
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599 hci_dev_unlock(hdev);
1600}
1601
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001602static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001604 struct hci_ev_conn_complete *ev = (void *) skb->data;
1605 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001607 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001608
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001610
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001611 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001612 if (!conn) {
1613 if (ev->link_type != SCO_LINK)
1614 goto unlock;
1615
1616 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1617 if (!conn)
1618 goto unlock;
1619
1620 conn->type = SCO_LINK;
1621 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001622
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001623 if (!ev->status) {
1624 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001625
1626 if (conn->type == ACL_LINK) {
1627 conn->state = BT_CONFIG;
1628 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001629
1630 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1631 !hci_find_link_key(hdev, &ev->bdaddr))
1632 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1633 else
1634 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001635 } else
1636 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001637
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001638 hci_conn_add_sysfs(conn);
1639
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001640 if (test_bit(HCI_AUTH, &hdev->flags))
1641 conn->link_mode |= HCI_LM_AUTH;
1642
1643 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1644 conn->link_mode |= HCI_LM_ENCRYPT;
1645
1646 /* Get remote features */
1647 if (conn->type == ACL_LINK) {
1648 struct hci_cp_read_remote_features cp;
1649 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001650 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001651 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001652 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001653
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001654 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001655 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001656 struct hci_cp_change_conn_ptype cp;
1657 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001658 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001659 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1660 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001661 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001662 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001663 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001664 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001665 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001666 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001667 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001668
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001669 if (conn->type == ACL_LINK)
1670 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001671
Marcel Holtmann769be972008-07-14 20:13:49 +02001672 if (ev->status) {
1673 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001674 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001675 } else if (ev->link_type != ACL_LINK)
1676 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001677
1678unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001680
1681 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682}
1683
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001684static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001686 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001688 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001690 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001691 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001693 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1694 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695
Szymon Janc138d22e2011-02-17 16:44:23 +01001696 if ((mask & HCI_LM_ACCEPT) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001697 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001699 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701
1702 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001703
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001704 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1705 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001706 memcpy(ie->data.dev_class, ev->dev_class, 3);
1707
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001708 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1709 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001711 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1712 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001713 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 hci_dev_unlock(hdev);
1715 return;
1716 }
1717 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001718
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001720
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 hci_dev_unlock(hdev);
1722
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001723 if (ev->link_type == ACL_LINK ||
1724 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001725 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001726 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001728 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001730 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1731 cp.role = 0x00; /* Become master */
1732 else
1733 cp.role = 0x01; /* Remain slave */
1734
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001735 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1736 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001737 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001738 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001739 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001740
1741 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001742 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001743
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001744 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1745 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1746 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001747 cp.content_format = cpu_to_le16(hdev->voice_setting);
1748 cp.retrans_effort = 0xff;
1749
1750 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001751 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001752 } else {
1753 conn->state = BT_CONNECT2;
1754 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001755 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 } else {
1757 /* Connection rejected */
1758 struct hci_cp_reject_conn_req cp;
1759
1760 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001761 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001762 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763 }
1764}
1765
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001766static u8 hci_to_mgmt_reason(u8 err)
1767{
1768 switch (err) {
1769 case HCI_ERROR_CONNECTION_TIMEOUT:
1770 return MGMT_DEV_DISCONN_TIMEOUT;
1771 case HCI_ERROR_REMOTE_USER_TERM:
1772 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1773 case HCI_ERROR_REMOTE_POWER_OFF:
1774 return MGMT_DEV_DISCONN_REMOTE;
1775 case HCI_ERROR_LOCAL_HOST_TERM:
1776 return MGMT_DEV_DISCONN_LOCAL_HOST;
1777 default:
1778 return MGMT_DEV_DISCONN_UNKNOWN;
1779 }
1780}
1781
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001782static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001784 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001785 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001787 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789 hci_dev_lock(hdev);
1790
Marcel Holtmann04837f62006-07-03 10:02:33 +02001791 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001792 if (!conn)
1793 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001794
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001795 if (ev->status == 0)
1796 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797
Johan Hedbergb644ba32012-01-17 21:48:47 +02001798 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001799 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001800 if (ev->status) {
Johan Hedberg88c3df12012-02-09 14:27:38 +02001801 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001802 conn->dst_type, ev->status);
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001803 } else {
1804 u8 reason = hci_to_mgmt_reason(ev->reason);
1805
Johan Hedbergafc747a2012-01-15 18:11:07 +02001806 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001807 conn->dst_type, reason);
1808 }
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001809 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001810
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001811 if (ev->status == 0) {
Johan Hedberg22102462013-10-05 12:01:06 +02001812 u8 type = conn->type;
1813
1814 if (type == ACL_LINK && conn->flush_key)
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301815 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001816 hci_proto_disconn_cfm(conn, ev->reason);
1817 hci_conn_del(conn);
Johan Hedberg22102462013-10-05 12:01:06 +02001818
1819 /* Re-enable advertising if necessary, since it might
1820 * have been disabled by the connection. From the
1821 * HCI_LE_Set_Advertise_Enable command description in
1822 * the core specification (v4.0):
1823 * "The Controller shall continue advertising until the Host
1824 * issues an LE_Set_Advertise_Enable command with
1825 * Advertising_Enable set to 0x00 (Advertising is disabled)
1826 * or until a connection is created or until the Advertising
1827 * is timed out due to Directed Advertising."
1828 */
1829 if (type == LE_LINK)
Marcel Holtmann5976e602013-10-06 04:08:14 -07001830 mgmt_reenable_advertising(hdev);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001831 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001832
1833unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 hci_dev_unlock(hdev);
1835}
1836
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001837static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001838{
1839 struct hci_ev_auth_complete *ev = (void *) skb->data;
1840 struct hci_conn *conn;
1841
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001842 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001843
1844 hci_dev_lock(hdev);
1845
1846 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001847 if (!conn)
1848 goto unlock;
1849
1850 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001851 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001852 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001853 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001854 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001855 conn->link_mode |= HCI_LM_AUTH;
1856 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001857 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001858 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001859 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001860 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001861 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001862
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001863 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1864 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001865
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001866 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001867 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001868 struct hci_cp_set_conn_encrypt cp;
1869 cp.handle = ev->handle;
1870 cp.encrypt = 0x01;
1871 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001872 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001873 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001874 conn->state = BT_CONNECTED;
1875 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001876 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001877 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001878 } else {
1879 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001880
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001881 hci_conn_hold(conn);
1882 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001883 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001884 }
1885
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001886 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001887 if (!ev->status) {
1888 struct hci_cp_set_conn_encrypt cp;
1889 cp.handle = ev->handle;
1890 cp.encrypt = 0x01;
1891 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001892 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001893 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001894 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001895 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001896 }
1897 }
1898
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001899unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001900 hci_dev_unlock(hdev);
1901}
1902
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001903static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001904{
Johan Hedberg127178d2010-11-18 22:22:29 +02001905 struct hci_ev_remote_name *ev = (void *) skb->data;
1906 struct hci_conn *conn;
1907
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001908 BT_DBG("%s", hdev->name);
1909
1910 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001911
1912 hci_dev_lock(hdev);
1913
1914 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001915
1916 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1917 goto check_auth;
1918
1919 if (ev->status == 0)
1920 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001921 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001922 else
1923 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1924
1925check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001926 if (!conn)
1927 goto unlock;
1928
1929 if (!hci_outgoing_auth_needed(hdev, conn))
1930 goto unlock;
1931
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001932 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001933 struct hci_cp_auth_requested cp;
1934 cp.handle = __cpu_to_le16(conn->handle);
1935 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1936 }
1937
Johan Hedberg79c6c702011-04-28 11:28:55 -07001938unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001939 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001940}
1941
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001942static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001943{
1944 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1945 struct hci_conn *conn;
1946
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001947 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001948
1949 hci_dev_lock(hdev);
1950
1951 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1952 if (conn) {
1953 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001954 if (ev->encrypt) {
1955 /* Encryption implies authentication */
1956 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001957 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001958 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001959 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001960 conn->link_mode &= ~HCI_LM_ENCRYPT;
1961 }
1962
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001963 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001964
Gustavo Padovana7d77232012-05-13 03:20:07 -03001965 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03001966 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02001967 hci_conn_drop(conn);
Gustavo Padovana7d77232012-05-13 03:20:07 -03001968 goto unlock;
1969 }
1970
Marcel Holtmannf8558552008-07-14 20:13:49 +02001971 if (conn->state == BT_CONFIG) {
1972 if (!ev->status)
1973 conn->state = BT_CONNECTED;
1974
1975 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001976 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001977 } else
1978 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001979 }
1980
Gustavo Padovana7d77232012-05-13 03:20:07 -03001981unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001982 hci_dev_unlock(hdev);
1983}
1984
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001985static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
1986 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001987{
1988 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1989 struct hci_conn *conn;
1990
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001991 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001992
1993 hci_dev_lock(hdev);
1994
1995 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1996 if (conn) {
1997 if (!ev->status)
1998 conn->link_mode |= HCI_LM_SECURE;
1999
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002000 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002001
2002 hci_key_change_cfm(conn, ev->status);
2003 }
2004
2005 hci_dev_unlock(hdev);
2006}
2007
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002008static void hci_remote_features_evt(struct hci_dev *hdev,
2009 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002010{
2011 struct hci_ev_remote_features *ev = (void *) skb->data;
2012 struct hci_conn *conn;
2013
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002014 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002015
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002016 hci_dev_lock(hdev);
2017
2018 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002019 if (!conn)
2020 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002021
Johan Hedbergccd556f2010-11-10 17:11:51 +02002022 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002023 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002024
2025 if (conn->state != BT_CONFIG)
2026 goto unlock;
2027
2028 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2029 struct hci_cp_read_remote_ext_features cp;
2030 cp.handle = ev->handle;
2031 cp.page = 0x01;
2032 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002033 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002034 goto unlock;
2035 }
2036
Johan Hedberg671267b2012-05-12 16:11:50 -03002037 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002038 struct hci_cp_remote_name_req cp;
2039 memset(&cp, 0, sizeof(cp));
2040 bacpy(&cp.bdaddr, &conn->dst);
2041 cp.pscan_rep_mode = 0x02;
2042 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002043 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2044 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002045 conn->dst_type, 0, NULL, 0,
2046 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002047
Johan Hedberg127178d2010-11-18 22:22:29 +02002048 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002049 conn->state = BT_CONNECTED;
2050 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002051 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002052 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002053
Johan Hedbergccd556f2010-11-10 17:11:51 +02002054unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002055 hci_dev_unlock(hdev);
2056}
2057
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002058static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002059{
2060 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002061 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002062 __u16 opcode;
2063
2064 skb_pull(skb, sizeof(*ev));
2065
2066 opcode = __le16_to_cpu(ev->opcode);
2067
2068 switch (opcode) {
2069 case HCI_OP_INQUIRY_CANCEL:
2070 hci_cc_inquiry_cancel(hdev, skb);
2071 break;
2072
Andre Guedes4d934832012-03-21 00:03:35 -03002073 case HCI_OP_PERIODIC_INQ:
2074 hci_cc_periodic_inq(hdev, skb);
2075 break;
2076
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002077 case HCI_OP_EXIT_PERIODIC_INQ:
2078 hci_cc_exit_periodic_inq(hdev, skb);
2079 break;
2080
2081 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2082 hci_cc_remote_name_req_cancel(hdev, skb);
2083 break;
2084
2085 case HCI_OP_ROLE_DISCOVERY:
2086 hci_cc_role_discovery(hdev, skb);
2087 break;
2088
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002089 case HCI_OP_READ_LINK_POLICY:
2090 hci_cc_read_link_policy(hdev, skb);
2091 break;
2092
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002093 case HCI_OP_WRITE_LINK_POLICY:
2094 hci_cc_write_link_policy(hdev, skb);
2095 break;
2096
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002097 case HCI_OP_READ_DEF_LINK_POLICY:
2098 hci_cc_read_def_link_policy(hdev, skb);
2099 break;
2100
2101 case HCI_OP_WRITE_DEF_LINK_POLICY:
2102 hci_cc_write_def_link_policy(hdev, skb);
2103 break;
2104
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002105 case HCI_OP_RESET:
2106 hci_cc_reset(hdev, skb);
2107 break;
2108
2109 case HCI_OP_WRITE_LOCAL_NAME:
2110 hci_cc_write_local_name(hdev, skb);
2111 break;
2112
2113 case HCI_OP_READ_LOCAL_NAME:
2114 hci_cc_read_local_name(hdev, skb);
2115 break;
2116
2117 case HCI_OP_WRITE_AUTH_ENABLE:
2118 hci_cc_write_auth_enable(hdev, skb);
2119 break;
2120
2121 case HCI_OP_WRITE_ENCRYPT_MODE:
2122 hci_cc_write_encrypt_mode(hdev, skb);
2123 break;
2124
2125 case HCI_OP_WRITE_SCAN_ENABLE:
2126 hci_cc_write_scan_enable(hdev, skb);
2127 break;
2128
2129 case HCI_OP_READ_CLASS_OF_DEV:
2130 hci_cc_read_class_of_dev(hdev, skb);
2131 break;
2132
2133 case HCI_OP_WRITE_CLASS_OF_DEV:
2134 hci_cc_write_class_of_dev(hdev, skb);
2135 break;
2136
2137 case HCI_OP_READ_VOICE_SETTING:
2138 hci_cc_read_voice_setting(hdev, skb);
2139 break;
2140
2141 case HCI_OP_WRITE_VOICE_SETTING:
2142 hci_cc_write_voice_setting(hdev, skb);
2143 break;
2144
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002145 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2146 hci_cc_read_num_supported_iac(hdev, skb);
2147 break;
2148
Marcel Holtmann333140b2008-07-14 20:13:48 +02002149 case HCI_OP_WRITE_SSP_MODE:
2150 hci_cc_write_ssp_mode(hdev, skb);
2151 break;
2152
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002153 case HCI_OP_READ_LOCAL_VERSION:
2154 hci_cc_read_local_version(hdev, skb);
2155 break;
2156
2157 case HCI_OP_READ_LOCAL_COMMANDS:
2158 hci_cc_read_local_commands(hdev, skb);
2159 break;
2160
2161 case HCI_OP_READ_LOCAL_FEATURES:
2162 hci_cc_read_local_features(hdev, skb);
2163 break;
2164
Andre Guedes971e3a42011-06-30 19:20:52 -03002165 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2166 hci_cc_read_local_ext_features(hdev, skb);
2167 break;
2168
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002169 case HCI_OP_READ_BUFFER_SIZE:
2170 hci_cc_read_buffer_size(hdev, skb);
2171 break;
2172
2173 case HCI_OP_READ_BD_ADDR:
2174 hci_cc_read_bd_addr(hdev, skb);
2175 break;
2176
Johan Hedbergf332ec62013-03-15 17:07:11 -05002177 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2178 hci_cc_read_page_scan_activity(hdev, skb);
2179 break;
2180
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002181 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2182 hci_cc_write_page_scan_activity(hdev, skb);
2183 break;
2184
Johan Hedbergf332ec62013-03-15 17:07:11 -05002185 case HCI_OP_READ_PAGE_SCAN_TYPE:
2186 hci_cc_read_page_scan_type(hdev, skb);
2187 break;
2188
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002189 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2190 hci_cc_write_page_scan_type(hdev, skb);
2191 break;
2192
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002193 case HCI_OP_READ_DATA_BLOCK_SIZE:
2194 hci_cc_read_data_block_size(hdev, skb);
2195 break;
2196
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002197 case HCI_OP_READ_FLOW_CONTROL_MODE:
2198 hci_cc_read_flow_control_mode(hdev, skb);
2199 break;
2200
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002201 case HCI_OP_READ_LOCAL_AMP_INFO:
2202 hci_cc_read_local_amp_info(hdev, skb);
2203 break;
2204
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002205 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2206 hci_cc_read_local_amp_assoc(hdev, skb);
2207 break;
2208
Johan Hedbergd5859e22011-01-25 01:19:58 +02002209 case HCI_OP_READ_INQ_RSP_TX_POWER:
2210 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2211 break;
2212
Johan Hedberg980e1a52011-01-22 06:10:07 +02002213 case HCI_OP_PIN_CODE_REPLY:
2214 hci_cc_pin_code_reply(hdev, skb);
2215 break;
2216
2217 case HCI_OP_PIN_CODE_NEG_REPLY:
2218 hci_cc_pin_code_neg_reply(hdev, skb);
2219 break;
2220
Szymon Jancc35938b2011-03-22 13:12:21 +01002221 case HCI_OP_READ_LOCAL_OOB_DATA:
2222 hci_cc_read_local_oob_data_reply(hdev, skb);
2223 break;
2224
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002225 case HCI_OP_LE_READ_BUFFER_SIZE:
2226 hci_cc_le_read_buffer_size(hdev, skb);
2227 break;
2228
Johan Hedberg60e77322013-01-22 14:01:59 +02002229 case HCI_OP_LE_READ_LOCAL_FEATURES:
2230 hci_cc_le_read_local_features(hdev, skb);
2231 break;
2232
Johan Hedberg8fa19092012-10-19 20:57:49 +03002233 case HCI_OP_LE_READ_ADV_TX_POWER:
2234 hci_cc_le_read_adv_tx_power(hdev, skb);
2235 break;
2236
Johan Hedberga5c29682011-02-19 12:05:57 -03002237 case HCI_OP_USER_CONFIRM_REPLY:
2238 hci_cc_user_confirm_reply(hdev, skb);
2239 break;
2240
2241 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2242 hci_cc_user_confirm_neg_reply(hdev, skb);
2243 break;
2244
Brian Gix1143d452011-11-23 08:28:34 -08002245 case HCI_OP_USER_PASSKEY_REPLY:
2246 hci_cc_user_passkey_reply(hdev, skb);
2247 break;
2248
2249 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2250 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002251 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002252
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002253 case HCI_OP_LE_SET_ADV_ENABLE:
2254 hci_cc_le_set_adv_enable(hdev, skb);
2255 break;
2256
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002257 case HCI_OP_LE_SET_SCAN_ENABLE:
2258 hci_cc_le_set_scan_enable(hdev, skb);
2259 break;
2260
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002261 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2262 hci_cc_le_read_white_list_size(hdev, skb);
2263 break;
2264
Johan Hedberg9b008c02013-01-22 14:02:01 +02002265 case HCI_OP_LE_READ_SUPPORTED_STATES:
2266 hci_cc_le_read_supported_states(hdev, skb);
2267 break;
2268
Andre Guedesf9b49302011-06-30 19:20:53 -03002269 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2270 hci_cc_write_le_host_supported(hdev, skb);
2271 break;
2272
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002273 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2274 hci_cc_write_remote_amp_assoc(hdev, skb);
2275 break;
2276
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002277 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002278 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002279 break;
2280 }
2281
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002282 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002283 del_timer(&hdev->cmd_timer);
2284
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002285 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002286
Szymon Jancdbccd792012-12-11 08:51:19 +01002287 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002288 atomic_set(&hdev->cmd_cnt, 1);
2289 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002290 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002291 }
2292}
2293
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002294static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002295{
2296 struct hci_ev_cmd_status *ev = (void *) skb->data;
2297 __u16 opcode;
2298
2299 skb_pull(skb, sizeof(*ev));
2300
2301 opcode = __le16_to_cpu(ev->opcode);
2302
2303 switch (opcode) {
2304 case HCI_OP_INQUIRY:
2305 hci_cs_inquiry(hdev, ev->status);
2306 break;
2307
2308 case HCI_OP_CREATE_CONN:
2309 hci_cs_create_conn(hdev, ev->status);
2310 break;
2311
2312 case HCI_OP_ADD_SCO:
2313 hci_cs_add_sco(hdev, ev->status);
2314 break;
2315
Marcel Holtmannf8558552008-07-14 20:13:49 +02002316 case HCI_OP_AUTH_REQUESTED:
2317 hci_cs_auth_requested(hdev, ev->status);
2318 break;
2319
2320 case HCI_OP_SET_CONN_ENCRYPT:
2321 hci_cs_set_conn_encrypt(hdev, ev->status);
2322 break;
2323
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002324 case HCI_OP_REMOTE_NAME_REQ:
2325 hci_cs_remote_name_req(hdev, ev->status);
2326 break;
2327
Marcel Holtmann769be972008-07-14 20:13:49 +02002328 case HCI_OP_READ_REMOTE_FEATURES:
2329 hci_cs_read_remote_features(hdev, ev->status);
2330 break;
2331
2332 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2333 hci_cs_read_remote_ext_features(hdev, ev->status);
2334 break;
2335
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002336 case HCI_OP_SETUP_SYNC_CONN:
2337 hci_cs_setup_sync_conn(hdev, ev->status);
2338 break;
2339
2340 case HCI_OP_SNIFF_MODE:
2341 hci_cs_sniff_mode(hdev, ev->status);
2342 break;
2343
2344 case HCI_OP_EXIT_SNIFF_MODE:
2345 hci_cs_exit_sniff_mode(hdev, ev->status);
2346 break;
2347
Johan Hedberg8962ee72011-01-20 12:40:27 +02002348 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002349 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002350 break;
2351
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002352 case HCI_OP_CREATE_PHY_LINK:
2353 hci_cs_create_phylink(hdev, ev->status);
2354 break;
2355
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002356 case HCI_OP_ACCEPT_PHY_LINK:
2357 hci_cs_accept_phylink(hdev, ev->status);
2358 break;
2359
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002360 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002361 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002362 break;
2363 }
2364
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002365 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002366 del_timer(&hdev->cmd_timer);
2367
Johan Hedberg02350a72013-04-03 21:50:29 +03002368 if (ev->status ||
2369 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2370 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002371
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002372 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002373 atomic_set(&hdev->cmd_cnt, 1);
2374 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002375 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002376 }
2377}
2378
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002379static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002380{
2381 struct hci_ev_role_change *ev = (void *) skb->data;
2382 struct hci_conn *conn;
2383
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002384 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002385
2386 hci_dev_lock(hdev);
2387
2388 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2389 if (conn) {
2390 if (!ev->status) {
2391 if (ev->role)
2392 conn->link_mode &= ~HCI_LM_MASTER;
2393 else
2394 conn->link_mode |= HCI_LM_MASTER;
2395 }
2396
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002397 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002398
2399 hci_role_switch_cfm(conn, ev->status, ev->role);
2400 }
2401
2402 hci_dev_unlock(hdev);
2403}
2404
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002405static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002406{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002407 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408 int i;
2409
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002410 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2411 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2412 return;
2413 }
2414
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002415 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002416 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002417 BT_DBG("%s bad parameters", hdev->name);
2418 return;
2419 }
2420
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002421 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2422
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002423 for (i = 0; i < ev->num_hndl; i++) {
2424 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002425 struct hci_conn *conn;
2426 __u16 handle, count;
2427
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002428 handle = __le16_to_cpu(info->handle);
2429 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002430
2431 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002432 if (!conn)
2433 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002434
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002435 conn->sent -= count;
2436
2437 switch (conn->type) {
2438 case ACL_LINK:
2439 hdev->acl_cnt += count;
2440 if (hdev->acl_cnt > hdev->acl_pkts)
2441 hdev->acl_cnt = hdev->acl_pkts;
2442 break;
2443
2444 case LE_LINK:
2445 if (hdev->le_pkts) {
2446 hdev->le_cnt += count;
2447 if (hdev->le_cnt > hdev->le_pkts)
2448 hdev->le_cnt = hdev->le_pkts;
2449 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002450 hdev->acl_cnt += count;
2451 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002452 hdev->acl_cnt = hdev->acl_pkts;
2453 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002454 break;
2455
2456 case SCO_LINK:
2457 hdev->sco_cnt += count;
2458 if (hdev->sco_cnt > hdev->sco_pkts)
2459 hdev->sco_cnt = hdev->sco_pkts;
2460 break;
2461
2462 default:
2463 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2464 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002465 }
2466 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002467
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002468 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002469}
2470
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002471static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2472 __u16 handle)
2473{
2474 struct hci_chan *chan;
2475
2476 switch (hdev->dev_type) {
2477 case HCI_BREDR:
2478 return hci_conn_hash_lookup_handle(hdev, handle);
2479 case HCI_AMP:
2480 chan = hci_chan_lookup_handle(hdev, handle);
2481 if (chan)
2482 return chan->conn;
2483 break;
2484 default:
2485 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2486 break;
2487 }
2488
2489 return NULL;
2490}
2491
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002492static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002493{
2494 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2495 int i;
2496
2497 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2498 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2499 return;
2500 }
2501
2502 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002503 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002504 BT_DBG("%s bad parameters", hdev->name);
2505 return;
2506 }
2507
2508 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002509 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002510
2511 for (i = 0; i < ev->num_hndl; i++) {
2512 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002513 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002514 __u16 handle, block_count;
2515
2516 handle = __le16_to_cpu(info->handle);
2517 block_count = __le16_to_cpu(info->blocks);
2518
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002519 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002520 if (!conn)
2521 continue;
2522
2523 conn->sent -= block_count;
2524
2525 switch (conn->type) {
2526 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002527 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002528 hdev->block_cnt += block_count;
2529 if (hdev->block_cnt > hdev->num_blocks)
2530 hdev->block_cnt = hdev->num_blocks;
2531 break;
2532
2533 default:
2534 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2535 break;
2536 }
2537 }
2538
2539 queue_work(hdev->workqueue, &hdev->tx_work);
2540}
2541
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002542static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002544 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002545 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002546
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002547 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548
2549 hci_dev_lock(hdev);
2550
Marcel Holtmann04837f62006-07-03 10:02:33 +02002551 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2552 if (conn) {
2553 conn->mode = ev->mode;
2554 conn->interval = __le16_to_cpu(ev->interval);
2555
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002556 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2557 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002558 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002559 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002560 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002561 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002562 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002563
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002564 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002565 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002566 }
2567
2568 hci_dev_unlock(hdev);
2569}
2570
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002571static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002572{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002573 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2574 struct hci_conn *conn;
2575
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002576 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002577
2578 hci_dev_lock(hdev);
2579
2580 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002581 if (!conn)
2582 goto unlock;
2583
2584 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002585 hci_conn_hold(conn);
2586 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002587 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002588 }
2589
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002590 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002591 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002592 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002593 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002594 u8 secure;
2595
2596 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2597 secure = 1;
2598 else
2599 secure = 0;
2600
Johan Hedberg744cf192011-11-08 20:40:14 +02002601 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002602 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002603
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002604unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002605 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606}
2607
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002608static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002610 struct hci_ev_link_key_req *ev = (void *) skb->data;
2611 struct hci_cp_link_key_reply cp;
2612 struct hci_conn *conn;
2613 struct link_key *key;
2614
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002615 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002616
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002617 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002618 return;
2619
2620 hci_dev_lock(hdev);
2621
2622 key = hci_find_link_key(hdev, &ev->bdaddr);
2623 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002624 BT_DBG("%s link key not found for %pMR", hdev->name,
2625 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002626 goto not_found;
2627 }
2628
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002629 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2630 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002631
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002632 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002633 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002634 BT_DBG("%s ignoring debug key", hdev->name);
2635 goto not_found;
2636 }
2637
2638 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002639 if (conn) {
2640 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002641 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002642 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2643 goto not_found;
2644 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002645
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002646 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002647 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002648 BT_DBG("%s ignoring key unauthenticated for high security",
2649 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002650 goto not_found;
2651 }
2652
2653 conn->key_type = key->type;
2654 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002655 }
2656
2657 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002658 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002659
2660 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2661
2662 hci_dev_unlock(hdev);
2663
2664 return;
2665
2666not_found:
2667 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2668 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669}
2670
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002671static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002672{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002673 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2674 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002675 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002676
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002677 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002678
2679 hci_dev_lock(hdev);
2680
2681 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2682 if (conn) {
2683 hci_conn_hold(conn);
2684 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002685 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002686
2687 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2688 conn->key_type = ev->key_type;
2689
David Herrmann76a68ba2013-04-06 20:28:37 +02002690 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002691 }
2692
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002693 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002694 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002695 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002696
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002697 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002698}
2699
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002700static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002701{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002702 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002703 struct hci_conn *conn;
2704
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002705 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002706
2707 hci_dev_lock(hdev);
2708
2709 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710 if (conn && !ev->status) {
2711 struct inquiry_entry *ie;
2712
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002713 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2714 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715 ie->data.clock_offset = ev->clock_offset;
2716 ie->timestamp = jiffies;
2717 }
2718 }
2719
2720 hci_dev_unlock(hdev);
2721}
2722
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002723static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002724{
2725 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2726 struct hci_conn *conn;
2727
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002728 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002729
2730 hci_dev_lock(hdev);
2731
2732 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2733 if (conn && !ev->status)
2734 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2735
2736 hci_dev_unlock(hdev);
2737}
2738
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002739static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002740{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002741 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002742 struct inquiry_entry *ie;
2743
2744 BT_DBG("%s", hdev->name);
2745
2746 hci_dev_lock(hdev);
2747
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002748 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2749 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002750 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2751 ie->timestamp = jiffies;
2752 }
2753
2754 hci_dev_unlock(hdev);
2755}
2756
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002757static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2758 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002759{
2760 struct inquiry_data data;
2761 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002762 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002763
2764 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2765
2766 if (!num_rsp)
2767 return;
2768
Andre Guedes1519cc12012-03-21 00:03:38 -03002769 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2770 return;
2771
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002772 hci_dev_lock(hdev);
2773
2774 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002775 struct inquiry_info_with_rssi_and_pscan_mode *info;
2776 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002777
Johan Hedberge17acd42011-03-30 23:57:16 +03002778 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002779 bacpy(&data.bdaddr, &info->bdaddr);
2780 data.pscan_rep_mode = info->pscan_rep_mode;
2781 data.pscan_period_mode = info->pscan_period_mode;
2782 data.pscan_mode = info->pscan_mode;
2783 memcpy(data.dev_class, info->dev_class, 3);
2784 data.clock_offset = info->clock_offset;
2785 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002786 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002787
2788 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002789 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002790 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002791 info->dev_class, info->rssi,
2792 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002793 }
2794 } else {
2795 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2796
Johan Hedberge17acd42011-03-30 23:57:16 +03002797 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002798 bacpy(&data.bdaddr, &info->bdaddr);
2799 data.pscan_rep_mode = info->pscan_rep_mode;
2800 data.pscan_period_mode = info->pscan_period_mode;
2801 data.pscan_mode = 0x00;
2802 memcpy(data.dev_class, info->dev_class, 3);
2803 data.clock_offset = info->clock_offset;
2804 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002805 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002806 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002807 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002808 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002809 info->dev_class, info->rssi,
2810 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002811 }
2812 }
2813
2814 hci_dev_unlock(hdev);
2815}
2816
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002817static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2818 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002819{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002820 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2821 struct hci_conn *conn;
2822
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002823 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002824
Marcel Holtmann41a96212008-07-14 20:13:48 +02002825 hci_dev_lock(hdev);
2826
2827 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002828 if (!conn)
2829 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002830
Johan Hedbergcad718e2013-04-17 15:00:51 +03002831 if (ev->page < HCI_MAX_PAGES)
2832 memcpy(conn->features[ev->page], ev->features, 8);
2833
Johan Hedbergccd556f2010-11-10 17:11:51 +02002834 if (!ev->status && ev->page == 0x01) {
2835 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002836
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002837 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2838 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002839 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002840
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302841 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002842 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302843 } else {
2844 /* It is mandatory by the Bluetooth specification that
2845 * Extended Inquiry Results are only used when Secure
2846 * Simple Pairing is enabled, but some devices violate
2847 * this.
2848 *
2849 * To make these devices work, the internal SSP
2850 * enabled flag needs to be cleared if the remote host
2851 * features do not indicate SSP support */
2852 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2853 }
Marcel Holtmann41a96212008-07-14 20:13:48 +02002854 }
2855
Johan Hedbergccd556f2010-11-10 17:11:51 +02002856 if (conn->state != BT_CONFIG)
2857 goto unlock;
2858
Johan Hedberg671267b2012-05-12 16:11:50 -03002859 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002860 struct hci_cp_remote_name_req cp;
2861 memset(&cp, 0, sizeof(cp));
2862 bacpy(&cp.bdaddr, &conn->dst);
2863 cp.pscan_rep_mode = 0x02;
2864 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002865 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2866 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002867 conn->dst_type, 0, NULL, 0,
2868 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002869
Johan Hedberg127178d2010-11-18 22:22:29 +02002870 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002871 conn->state = BT_CONNECTED;
2872 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002873 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002874 }
2875
2876unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002877 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002878}
2879
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002880static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2881 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002882{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002883 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2884 struct hci_conn *conn;
2885
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002886 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002887
2888 hci_dev_lock(hdev);
2889
2890 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002891 if (!conn) {
2892 if (ev->link_type == ESCO_LINK)
2893 goto unlock;
2894
2895 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2896 if (!conn)
2897 goto unlock;
2898
2899 conn->type = SCO_LINK;
2900 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002901
Marcel Holtmann732547f2009-04-19 19:14:14 +02002902 switch (ev->status) {
2903 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002904 conn->handle = __le16_to_cpu(ev->handle);
2905 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002906
2907 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002908 break;
2909
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02002910 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05002911 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002912 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002913 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002914 case 0x1f: /* Unspecified error */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002915 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02002916 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2917 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002918 if (hci_setup_sync(conn, conn->link->handle))
2919 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002920 }
2921 /* fall through */
2922
2923 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002924 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002925 break;
2926 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002927
2928 hci_proto_connect_cfm(conn, ev->status);
2929 if (ev->status)
2930 hci_conn_del(conn);
2931
2932unlock:
2933 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002934}
2935
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002936static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
2937 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002938{
2939 struct inquiry_data data;
2940 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2941 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302942 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002943
2944 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2945
2946 if (!num_rsp)
2947 return;
2948
Andre Guedes1519cc12012-03-21 00:03:38 -03002949 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2950 return;
2951
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002952 hci_dev_lock(hdev);
2953
Johan Hedberge17acd42011-03-30 23:57:16 +03002954 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002955 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002956
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002957 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002958 data.pscan_rep_mode = info->pscan_rep_mode;
2959 data.pscan_period_mode = info->pscan_period_mode;
2960 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002961 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002962 data.clock_offset = info->clock_offset;
2963 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002964 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002965
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002966 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002967 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002968 sizeof(info->data),
2969 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002970 else
2971 name_known = true;
2972
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002973 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002974 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302975 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02002976 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002977 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302978 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002979 }
2980
2981 hci_dev_unlock(hdev);
2982}
2983
Johan Hedberg1c2e0042012-06-08 23:31:13 +08002984static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
2985 struct sk_buff *skb)
2986{
2987 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
2988 struct hci_conn *conn;
2989
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002990 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08002991 __le16_to_cpu(ev->handle));
2992
2993 hci_dev_lock(hdev);
2994
2995 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2996 if (!conn)
2997 goto unlock;
2998
2999 if (!ev->status)
3000 conn->sec_level = conn->pending_sec_level;
3001
3002 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3003
3004 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003005 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003006 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003007 goto unlock;
3008 }
3009
3010 if (conn->state == BT_CONFIG) {
3011 if (!ev->status)
3012 conn->state = BT_CONNECTED;
3013
3014 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003015 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003016 } else {
3017 hci_auth_cfm(conn, ev->status);
3018
3019 hci_conn_hold(conn);
3020 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003021 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003022 }
3023
3024unlock:
3025 hci_dev_unlock(hdev);
3026}
3027
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003028static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003029{
3030 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003031 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3032 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003033 /* If both remote and local IO capabilities allow MITM
3034 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003035 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3036 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3037 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003038 else
Mikel Astizacabae92013-06-28 10:56:28 +02003039 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003040 }
3041
3042 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003043 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3044 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003045 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003046
3047 return conn->auth_type;
3048}
3049
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003050static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003051{
3052 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3053 struct hci_conn *conn;
3054
3055 BT_DBG("%s", hdev->name);
3056
3057 hci_dev_lock(hdev);
3058
3059 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003060 if (!conn)
3061 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003062
Johan Hedberg03b555e2011-01-04 15:40:05 +02003063 hci_conn_hold(conn);
3064
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003065 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003066 goto unlock;
3067
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003068 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003069 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003070 struct hci_cp_io_capability_reply cp;
3071
3072 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303073 /* Change the IO capability from KeyboardDisplay
3074 * to DisplayYesNo as it is not supported by BT spec. */
3075 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003076 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003077 conn->auth_type = hci_get_auth_req(conn);
3078 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003079
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003080 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3081 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003082 cp.oob_data = 0x01;
3083 else
3084 cp.oob_data = 0x00;
3085
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003086 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003087 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003088 } else {
3089 struct hci_cp_io_capability_neg_reply cp;
3090
3091 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003092 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003093
3094 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003095 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003096 }
3097
3098unlock:
3099 hci_dev_unlock(hdev);
3100}
3101
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003102static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003103{
3104 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3105 struct hci_conn *conn;
3106
3107 BT_DBG("%s", hdev->name);
3108
3109 hci_dev_lock(hdev);
3110
3111 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3112 if (!conn)
3113 goto unlock;
3114
Johan Hedberg03b555e2011-01-04 15:40:05 +02003115 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003116 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003117 if (ev->oob_data)
3118 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003119
3120unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003121 hci_dev_unlock(hdev);
3122}
3123
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003124static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3125 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003126{
3127 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003128 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003129 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003130
3131 BT_DBG("%s", hdev->name);
3132
3133 hci_dev_lock(hdev);
3134
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003135 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003136 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003137
Johan Hedberg7a828902011-04-28 11:28:53 -07003138 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3139 if (!conn)
3140 goto unlock;
3141
3142 loc_mitm = (conn->auth_type & 0x01);
3143 rem_mitm = (conn->remote_auth & 0x01);
3144
3145 /* If we require MITM but the remote device can't provide that
3146 * (it has NoInputNoOutput) then reject the confirmation
3147 * request. The only exception is when we're dedicated bonding
3148 * initiators (connect_cfm_cb set) since then we always have the MITM
3149 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003150 if (!conn->connect_cfm_cb && loc_mitm &&
3151 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003152 BT_DBG("Rejecting request: remote device can't provide MITM");
3153 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003154 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003155 goto unlock;
3156 }
3157
3158 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003159 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3160 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003161
3162 /* If we're not the initiators request authorization to
3163 * proceed from user space (mgmt_user_confirm with
3164 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003165 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003166 BT_DBG("Confirming auto-accept as acceptor");
3167 confirm_hint = 1;
3168 goto confirm;
3169 }
3170
Johan Hedberg9f616562011-04-28 11:28:54 -07003171 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003172 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003173
3174 if (hdev->auto_accept_delay > 0) {
3175 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3176 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3177 goto unlock;
3178 }
3179
Johan Hedberg7a828902011-04-28 11:28:53 -07003180 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003181 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003182 goto unlock;
3183 }
3184
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003185confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003186 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003187 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003188
3189unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003190 hci_dev_unlock(hdev);
3191}
3192
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003193static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3194 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003195{
3196 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3197
3198 BT_DBG("%s", hdev->name);
3199
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003200 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003201 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003202}
3203
Johan Hedberg92a25252012-09-06 18:39:26 +03003204static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3205 struct sk_buff *skb)
3206{
3207 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3208 struct hci_conn *conn;
3209
3210 BT_DBG("%s", hdev->name);
3211
3212 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3213 if (!conn)
3214 return;
3215
3216 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3217 conn->passkey_entered = 0;
3218
3219 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3220 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3221 conn->dst_type, conn->passkey_notify,
3222 conn->passkey_entered);
3223}
3224
3225static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3226{
3227 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3228 struct hci_conn *conn;
3229
3230 BT_DBG("%s", hdev->name);
3231
3232 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3233 if (!conn)
3234 return;
3235
3236 switch (ev->type) {
3237 case HCI_KEYPRESS_STARTED:
3238 conn->passkey_entered = 0;
3239 return;
3240
3241 case HCI_KEYPRESS_ENTERED:
3242 conn->passkey_entered++;
3243 break;
3244
3245 case HCI_KEYPRESS_ERASED:
3246 conn->passkey_entered--;
3247 break;
3248
3249 case HCI_KEYPRESS_CLEARED:
3250 conn->passkey_entered = 0;
3251 break;
3252
3253 case HCI_KEYPRESS_COMPLETED:
3254 return;
3255 }
3256
3257 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3258 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3259 conn->dst_type, conn->passkey_notify,
3260 conn->passkey_entered);
3261}
3262
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003263static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3264 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003265{
3266 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3267 struct hci_conn *conn;
3268
3269 BT_DBG("%s", hdev->name);
3270
3271 hci_dev_lock(hdev);
3272
3273 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003274 if (!conn)
3275 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003276
Johan Hedberg2a611692011-02-19 12:06:00 -03003277 /* To avoid duplicate auth_failed events to user space we check
3278 * the HCI_CONN_AUTH_PEND flag which will be set if we
3279 * initiated the authentication. A traditional auth_complete
3280 * event gets always produced as initiator and is also mapped to
3281 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003282 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003283 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003284 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003285
David Herrmann76a68ba2013-04-06 20:28:37 +02003286 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003287
3288unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003289 hci_dev_unlock(hdev);
3290}
3291
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003292static void hci_remote_host_features_evt(struct hci_dev *hdev,
3293 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003294{
3295 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3296 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003297 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003298
3299 BT_DBG("%s", hdev->name);
3300
3301 hci_dev_lock(hdev);
3302
Johan Hedbergcad718e2013-04-17 15:00:51 +03003303 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3304 if (conn)
3305 memcpy(conn->features[1], ev->features, 8);
3306
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003307 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3308 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003309 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003310
3311 hci_dev_unlock(hdev);
3312}
3313
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003314static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3315 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003316{
3317 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3318 struct oob_data *data;
3319
3320 BT_DBG("%s", hdev->name);
3321
3322 hci_dev_lock(hdev);
3323
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003324 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003325 goto unlock;
3326
Szymon Janc2763eda2011-03-22 13:12:22 +01003327 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3328 if (data) {
3329 struct hci_cp_remote_oob_data_reply cp;
3330
3331 bacpy(&cp.bdaddr, &ev->bdaddr);
3332 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3333 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3334
3335 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003336 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003337 } else {
3338 struct hci_cp_remote_oob_data_neg_reply cp;
3339
3340 bacpy(&cp.bdaddr, &ev->bdaddr);
3341 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003342 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003343 }
3344
Szymon Jance1ba1f12011-04-06 13:01:59 +02003345unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003346 hci_dev_unlock(hdev);
3347}
3348
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003349static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3350 struct sk_buff *skb)
3351{
3352 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3353 struct hci_conn *hcon, *bredr_hcon;
3354
3355 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3356 ev->status);
3357
3358 hci_dev_lock(hdev);
3359
3360 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3361 if (!hcon) {
3362 hci_dev_unlock(hdev);
3363 return;
3364 }
3365
3366 if (ev->status) {
3367 hci_conn_del(hcon);
3368 hci_dev_unlock(hdev);
3369 return;
3370 }
3371
3372 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3373
3374 hcon->state = BT_CONNECTED;
3375 bacpy(&hcon->dst, &bredr_hcon->dst);
3376
3377 hci_conn_hold(hcon);
3378 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003379 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003380
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003381 hci_conn_add_sysfs(hcon);
3382
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003383 amp_physical_cfm(bredr_hcon, hcon);
3384
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003385 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003386}
3387
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003388static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3389{
3390 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3391 struct hci_conn *hcon;
3392 struct hci_chan *hchan;
3393 struct amp_mgr *mgr;
3394
3395 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3396 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3397 ev->status);
3398
3399 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3400 if (!hcon)
3401 return;
3402
3403 /* Create AMP hchan */
3404 hchan = hci_chan_create(hcon);
3405 if (!hchan)
3406 return;
3407
3408 hchan->handle = le16_to_cpu(ev->handle);
3409
3410 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3411
3412 mgr = hcon->amp_mgr;
3413 if (mgr && mgr->bredr_chan) {
3414 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3415
3416 l2cap_chan_lock(bredr_chan);
3417
3418 bredr_chan->conn->mtu = hdev->block_mtu;
3419 l2cap_logical_cfm(bredr_chan, hchan, 0);
3420 hci_conn_hold(hcon);
3421
3422 l2cap_chan_unlock(bredr_chan);
3423 }
3424}
3425
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003426static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3427 struct sk_buff *skb)
3428{
3429 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3430 struct hci_chan *hchan;
3431
3432 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3433 le16_to_cpu(ev->handle), ev->status);
3434
3435 if (ev->status)
3436 return;
3437
3438 hci_dev_lock(hdev);
3439
3440 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3441 if (!hchan)
3442 goto unlock;
3443
3444 amp_destroy_logical_link(hchan, ev->reason);
3445
3446unlock:
3447 hci_dev_unlock(hdev);
3448}
3449
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003450static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3451 struct sk_buff *skb)
3452{
3453 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3454 struct hci_conn *hcon;
3455
3456 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3457
3458 if (ev->status)
3459 return;
3460
3461 hci_dev_lock(hdev);
3462
3463 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3464 if (hcon) {
3465 hcon->state = BT_CLOSED;
3466 hci_conn_del(hcon);
3467 }
3468
3469 hci_dev_unlock(hdev);
3470}
3471
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003472static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003473{
3474 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3475 struct hci_conn *conn;
3476
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003477 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003478
3479 hci_dev_lock(hdev);
3480
Andre Guedesb47a09b2012-07-27 15:10:15 -03003481 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003482 if (!conn) {
3483 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3484 if (!conn) {
3485 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003486 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003487 }
Andre Guedes29b79882011-05-31 14:20:54 -03003488
3489 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003490
Marcel Holtmann880be4e2013-10-13 07:25:18 -07003491 /* The advertising parameters for own address type
3492 * define which source address and source address
3493 * type this connections has.
3494 */
3495 if (bacmp(&conn->src, BDADDR_ANY)) {
3496 conn->src_type = ADDR_LE_DEV_PUBLIC;
3497 } else {
3498 bacpy(&conn->src, &hdev->static_addr);
3499 conn->src_type = ADDR_LE_DEV_RANDOM;
3500 }
3501
Andre Guedesb9b343d2012-07-27 15:10:11 -03003502 if (ev->role == LE_CONN_ROLE_MASTER) {
3503 conn->out = true;
3504 conn->link_mode |= HCI_LM_MASTER;
3505 }
Ville Tervob62f3282011-02-10 22:38:50 -03003506 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003507
Andre Guedescd17dec2012-07-27 15:10:16 -03003508 if (ev->status) {
3509 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3510 conn->dst_type, ev->status);
3511 hci_proto_connect_cfm(conn, ev->status);
3512 conn->state = BT_CLOSED;
3513 hci_conn_del(conn);
3514 goto unlock;
3515 }
3516
Johan Hedbergb644ba32012-01-17 21:48:47 +02003517 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3518 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003519 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003520
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003521 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003522 conn->handle = __le16_to_cpu(ev->handle);
3523 conn->state = BT_CONNECTED;
3524
Ville Tervofcd89c02011-02-10 22:38:47 -03003525 hci_conn_add_sysfs(conn);
3526
3527 hci_proto_connect_cfm(conn, ev->status);
3528
3529unlock:
3530 hci_dev_unlock(hdev);
3531}
3532
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003533static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003534{
Andre Guedese95beb42011-09-26 20:48:35 -03003535 u8 num_reports = skb->data[0];
3536 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003537 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003538
Andre Guedese95beb42011-09-26 20:48:35 -03003539 while (num_reports--) {
3540 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003541
Andre Guedes3c9e9192012-01-10 18:20:50 -03003542 rssi = ev->data[ev->length];
3543 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003544 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003545
Andre Guedese95beb42011-09-26 20:48:35 -03003546 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003547 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003548}
3549
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003550static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003551{
3552 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3553 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003554 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003555 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003556 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003557
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003558 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003559
3560 hci_dev_lock(hdev);
3561
3562 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003563 if (conn == NULL)
3564 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003565
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003566 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3567 if (ltk == NULL)
3568 goto not_found;
3569
3570 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003571 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003572
3573 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03003574 conn->pending_sec_level = BT_SECURITY_HIGH;
3575 else
3576 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003577
Andre Guedes89cbb4d2013-07-31 16:25:29 -03003578 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003579
3580 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3581
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003582 if (ltk->type & HCI_SMP_STK) {
3583 list_del(&ltk->list);
3584 kfree(ltk);
3585 }
3586
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003587 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003588
3589 return;
3590
3591not_found:
3592 neg.handle = ev->handle;
3593 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3594 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003595}
3596
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003597static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003598{
3599 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3600
3601 skb_pull(skb, sizeof(*le_ev));
3602
3603 switch (le_ev->subevent) {
3604 case HCI_EV_LE_CONN_COMPLETE:
3605 hci_le_conn_complete_evt(hdev, skb);
3606 break;
3607
Andre Guedes9aa04c92011-05-26 16:23:51 -03003608 case HCI_EV_LE_ADVERTISING_REPORT:
3609 hci_le_adv_report_evt(hdev, skb);
3610 break;
3611
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003612 case HCI_EV_LE_LTK_REQ:
3613 hci_le_ltk_request_evt(hdev, skb);
3614 break;
3615
Ville Tervofcd89c02011-02-10 22:38:47 -03003616 default:
3617 break;
3618 }
3619}
3620
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003621static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3622{
3623 struct hci_ev_channel_selected *ev = (void *) skb->data;
3624 struct hci_conn *hcon;
3625
3626 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3627
3628 skb_pull(skb, sizeof(*ev));
3629
3630 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3631 if (!hcon)
3632 return;
3633
3634 amp_read_loc_assoc_final_data(hdev, hcon);
3635}
3636
Linus Torvalds1da177e2005-04-16 15:20:36 -07003637void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3638{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003639 struct hci_event_hdr *hdr = (void *) skb->data;
3640 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003641
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003642 hci_dev_lock(hdev);
3643
3644 /* Received events are (currently) only needed when a request is
3645 * ongoing so avoid unnecessary memory allocation.
3646 */
3647 if (hdev->req_status == HCI_REQ_PEND) {
3648 kfree_skb(hdev->recv_evt);
3649 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3650 }
3651
3652 hci_dev_unlock(hdev);
3653
Linus Torvalds1da177e2005-04-16 15:20:36 -07003654 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3655
Johan Hedberg02350a72013-04-03 21:50:29 +03003656 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02003657 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
3658 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03003659
3660 hci_req_cmd_complete(hdev, opcode, 0);
3661 }
3662
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003663 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664 case HCI_EV_INQUIRY_COMPLETE:
3665 hci_inquiry_complete_evt(hdev, skb);
3666 break;
3667
3668 case HCI_EV_INQUIRY_RESULT:
3669 hci_inquiry_result_evt(hdev, skb);
3670 break;
3671
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003672 case HCI_EV_CONN_COMPLETE:
3673 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003674 break;
3675
Linus Torvalds1da177e2005-04-16 15:20:36 -07003676 case HCI_EV_CONN_REQUEST:
3677 hci_conn_request_evt(hdev, skb);
3678 break;
3679
Linus Torvalds1da177e2005-04-16 15:20:36 -07003680 case HCI_EV_DISCONN_COMPLETE:
3681 hci_disconn_complete_evt(hdev, skb);
3682 break;
3683
Linus Torvalds1da177e2005-04-16 15:20:36 -07003684 case HCI_EV_AUTH_COMPLETE:
3685 hci_auth_complete_evt(hdev, skb);
3686 break;
3687
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003688 case HCI_EV_REMOTE_NAME:
3689 hci_remote_name_evt(hdev, skb);
3690 break;
3691
Linus Torvalds1da177e2005-04-16 15:20:36 -07003692 case HCI_EV_ENCRYPT_CHANGE:
3693 hci_encrypt_change_evt(hdev, skb);
3694 break;
3695
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003696 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3697 hci_change_link_key_complete_evt(hdev, skb);
3698 break;
3699
3700 case HCI_EV_REMOTE_FEATURES:
3701 hci_remote_features_evt(hdev, skb);
3702 break;
3703
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003704 case HCI_EV_CMD_COMPLETE:
3705 hci_cmd_complete_evt(hdev, skb);
3706 break;
3707
3708 case HCI_EV_CMD_STATUS:
3709 hci_cmd_status_evt(hdev, skb);
3710 break;
3711
3712 case HCI_EV_ROLE_CHANGE:
3713 hci_role_change_evt(hdev, skb);
3714 break;
3715
3716 case HCI_EV_NUM_COMP_PKTS:
3717 hci_num_comp_pkts_evt(hdev, skb);
3718 break;
3719
3720 case HCI_EV_MODE_CHANGE:
3721 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003722 break;
3723
3724 case HCI_EV_PIN_CODE_REQ:
3725 hci_pin_code_request_evt(hdev, skb);
3726 break;
3727
3728 case HCI_EV_LINK_KEY_REQ:
3729 hci_link_key_request_evt(hdev, skb);
3730 break;
3731
3732 case HCI_EV_LINK_KEY_NOTIFY:
3733 hci_link_key_notify_evt(hdev, skb);
3734 break;
3735
3736 case HCI_EV_CLOCK_OFFSET:
3737 hci_clock_offset_evt(hdev, skb);
3738 break;
3739
Marcel Holtmanna8746412008-07-14 20:13:46 +02003740 case HCI_EV_PKT_TYPE_CHANGE:
3741 hci_pkt_type_change_evt(hdev, skb);
3742 break;
3743
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003744 case HCI_EV_PSCAN_REP_MODE:
3745 hci_pscan_rep_mode_evt(hdev, skb);
3746 break;
3747
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003748 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3749 hci_inquiry_result_with_rssi_evt(hdev, skb);
3750 break;
3751
3752 case HCI_EV_REMOTE_EXT_FEATURES:
3753 hci_remote_ext_features_evt(hdev, skb);
3754 break;
3755
3756 case HCI_EV_SYNC_CONN_COMPLETE:
3757 hci_sync_conn_complete_evt(hdev, skb);
3758 break;
3759
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003760 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3761 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003762 break;
3763
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003764 case HCI_EV_KEY_REFRESH_COMPLETE:
3765 hci_key_refresh_complete_evt(hdev, skb);
3766 break;
3767
Marcel Holtmann04936842008-07-14 20:13:48 +02003768 case HCI_EV_IO_CAPA_REQUEST:
3769 hci_io_capa_request_evt(hdev, skb);
3770 break;
3771
Johan Hedberg03b555e2011-01-04 15:40:05 +02003772 case HCI_EV_IO_CAPA_REPLY:
3773 hci_io_capa_reply_evt(hdev, skb);
3774 break;
3775
Johan Hedberga5c29682011-02-19 12:05:57 -03003776 case HCI_EV_USER_CONFIRM_REQUEST:
3777 hci_user_confirm_request_evt(hdev, skb);
3778 break;
3779
Brian Gix1143d452011-11-23 08:28:34 -08003780 case HCI_EV_USER_PASSKEY_REQUEST:
3781 hci_user_passkey_request_evt(hdev, skb);
3782 break;
3783
Johan Hedberg92a25252012-09-06 18:39:26 +03003784 case HCI_EV_USER_PASSKEY_NOTIFY:
3785 hci_user_passkey_notify_evt(hdev, skb);
3786 break;
3787
3788 case HCI_EV_KEYPRESS_NOTIFY:
3789 hci_keypress_notify_evt(hdev, skb);
3790 break;
3791
Marcel Holtmann04936842008-07-14 20:13:48 +02003792 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3793 hci_simple_pair_complete_evt(hdev, skb);
3794 break;
3795
Marcel Holtmann41a96212008-07-14 20:13:48 +02003796 case HCI_EV_REMOTE_HOST_FEATURES:
3797 hci_remote_host_features_evt(hdev, skb);
3798 break;
3799
Ville Tervofcd89c02011-02-10 22:38:47 -03003800 case HCI_EV_LE_META:
3801 hci_le_meta_evt(hdev, skb);
3802 break;
3803
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003804 case HCI_EV_CHANNEL_SELECTED:
3805 hci_chan_selected_evt(hdev, skb);
3806 break;
3807
Szymon Janc2763eda2011-03-22 13:12:22 +01003808 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3809 hci_remote_oob_data_request_evt(hdev, skb);
3810 break;
3811
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003812 case HCI_EV_PHY_LINK_COMPLETE:
3813 hci_phy_link_complete_evt(hdev, skb);
3814 break;
3815
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003816 case HCI_EV_LOGICAL_LINK_COMPLETE:
3817 hci_loglink_complete_evt(hdev, skb);
3818 break;
3819
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003820 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3821 hci_disconn_loglink_complete_evt(hdev, skb);
3822 break;
3823
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003824 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3825 hci_disconn_phylink_complete_evt(hdev, skb);
3826 break;
3827
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003828 case HCI_EV_NUM_COMP_BLOCKS:
3829 hci_num_comp_blocks_evt(hdev, skb);
3830 break;
3831
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003832 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003833 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003834 break;
3835 }
3836
3837 kfree_skb(skb);
3838 hdev->stat.evt_rx++;
3839}