blob: 5391469ff1a562f40bd70c2e60646b66d7b9c608 [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 Hedbergc6d887a2013-10-14 16:20:07 +0300942 if (*sent && !test_bit(HCI_INIT, &hdev->flags)) {
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500943 struct hci_request req;
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100944
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500945 hci_req_init(&req, hdev);
946 hci_update_ad(&req);
947 hci_req_run(&req, NULL);
948 }
949
950 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100951}
952
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300953static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300954 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300955{
956 struct hci_cp_le_set_scan_enable *cp;
957 __u8 status = *((__u8 *) skb->data);
958
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300959 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300960
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300961 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
962 if (!cp)
963 return;
964
Andre Guedes3fd319b2013-04-30 15:29:36 -0300965 if (status)
966 return;
967
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200968 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -0300969 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300970 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200971 break;
972
Andre Guedes76a388b2013-04-04 20:21:02 -0300973 case LE_SCAN_DISABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300974 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200975 break;
976
977 default:
978 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
979 break;
Andre Guedes35815082011-05-26 16:23:53 -0300980 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300981}
982
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200983static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
984 struct sk_buff *skb)
985{
986 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
987
988 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
989
990 if (!rp->status)
991 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200992}
993
Johan Hedberg9b008c02013-01-22 14:02:01 +0200994static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
995 struct sk_buff *skb)
996{
997 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
998
999 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1000
1001 if (!rp->status)
1002 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +02001003}
1004
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001005static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1006 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001007{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001008 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001009 __u8 status = *((__u8 *) skb->data);
1010
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001011 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001012
Johan Hedberg06199cf2012-02-22 16:37:11 +02001013 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001014 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001015 return;
1016
Johan Hedberg8f984df2012-02-28 01:07:22 +02001017 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001018 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001019 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001020 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1021 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001022 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001023 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001024 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001025 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001026
1027 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001028 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001029 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001030 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001031 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001032}
1033
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001034static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1035 struct sk_buff *skb)
1036{
1037 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1038
1039 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1040 hdev->name, rp->status, rp->phy_handle);
1041
1042 if (rp->status)
1043 return;
1044
1045 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1046}
1047
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001048static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001049{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001050 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001051
1052 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001053 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001054 return;
1055 }
1056
Andre Guedes89352e72011-11-04 14:16:53 -03001057 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001058}
1059
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001060static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001062 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001065 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001066
1067 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068 if (!cp)
1069 return;
1070
1071 hci_dev_lock(hdev);
1072
1073 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1074
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001075 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076
1077 if (status) {
1078 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001079 if (status != 0x0c || conn->attempt > 2) {
1080 conn->state = BT_CLOSED;
1081 hci_proto_connect_cfm(conn, status);
1082 hci_conn_del(conn);
1083 } else
1084 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 }
1086 } else {
1087 if (!conn) {
1088 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1089 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001090 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 conn->link_mode |= HCI_LM_MASTER;
1092 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001093 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 }
1095 }
1096
1097 hci_dev_unlock(hdev);
1098}
1099
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001100static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001102 struct hci_cp_add_sco *cp;
1103 struct hci_conn *acl, *sco;
1104 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001106 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001107
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001108 if (!status)
1109 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001111 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1112 if (!cp)
1113 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001115 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001117 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001118
1119 hci_dev_lock(hdev);
1120
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001121 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001122 if (acl) {
1123 sco = acl->link;
1124 if (sco) {
1125 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001126
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001127 hci_proto_connect_cfm(sco, status);
1128 hci_conn_del(sco);
1129 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001130 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001131
1132 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133}
1134
Marcel Holtmannf8558552008-07-14 20:13:49 +02001135static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1136{
1137 struct hci_cp_auth_requested *cp;
1138 struct hci_conn *conn;
1139
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001140 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001141
1142 if (!status)
1143 return;
1144
1145 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1146 if (!cp)
1147 return;
1148
1149 hci_dev_lock(hdev);
1150
1151 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1152 if (conn) {
1153 if (conn->state == BT_CONFIG) {
1154 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001155 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001156 }
1157 }
1158
1159 hci_dev_unlock(hdev);
1160}
1161
1162static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1163{
1164 struct hci_cp_set_conn_encrypt *cp;
1165 struct hci_conn *conn;
1166
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001167 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001168
1169 if (!status)
1170 return;
1171
1172 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1173 if (!cp)
1174 return;
1175
1176 hci_dev_lock(hdev);
1177
1178 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1179 if (conn) {
1180 if (conn->state == BT_CONFIG) {
1181 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001182 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001183 }
1184 }
1185
1186 hci_dev_unlock(hdev);
1187}
1188
Johan Hedberg127178d2010-11-18 22:22:29 +02001189static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001190 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001191{
Johan Hedberg392599b2010-11-18 22:22:28 +02001192 if (conn->state != BT_CONFIG || !conn->out)
1193 return 0;
1194
Johan Hedberg765c2a92011-01-19 12:06:52 +05301195 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001196 return 0;
1197
1198 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001199 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001200 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1201 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001202 return 0;
1203
Johan Hedberg392599b2010-11-18 22:22:28 +02001204 return 1;
1205}
1206
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001207static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001208 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001209{
1210 struct hci_cp_remote_name_req cp;
1211
1212 memset(&cp, 0, sizeof(cp));
1213
1214 bacpy(&cp.bdaddr, &e->data.bdaddr);
1215 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1216 cp.pscan_mode = e->data.pscan_mode;
1217 cp.clock_offset = e->data.clock_offset;
1218
1219 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1220}
1221
Johan Hedbergb644ba32012-01-17 21:48:47 +02001222static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001223{
1224 struct discovery_state *discov = &hdev->discovery;
1225 struct inquiry_entry *e;
1226
Johan Hedbergb644ba32012-01-17 21:48:47 +02001227 if (list_empty(&discov->resolve))
1228 return false;
1229
1230 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001231 if (!e)
1232 return false;
1233
Johan Hedbergb644ba32012-01-17 21:48:47 +02001234 if (hci_resolve_name(hdev, e) == 0) {
1235 e->name_state = NAME_PENDING;
1236 return true;
1237 }
1238
1239 return false;
1240}
1241
1242static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001243 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001244{
1245 struct discovery_state *discov = &hdev->discovery;
1246 struct inquiry_entry *e;
1247
1248 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001249 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1250 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001251
1252 if (discov->state == DISCOVERY_STOPPED)
1253 return;
1254
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001255 if (discov->state == DISCOVERY_STOPPING)
1256 goto discov_complete;
1257
1258 if (discov->state != DISCOVERY_RESOLVING)
1259 return;
1260
1261 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001262 /* If the device was not found in a list of found devices names of which
1263 * are pending. there is no need to continue resolving a next name as it
1264 * will be done upon receiving another Remote Name Request Complete
1265 * Event */
1266 if (!e)
1267 return;
1268
1269 list_del(&e->list);
1270 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001271 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001272 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1273 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001274 } else {
1275 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001276 }
1277
Johan Hedbergb644ba32012-01-17 21:48:47 +02001278 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001279 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001280
1281discov_complete:
1282 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1283}
1284
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001285static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1286{
Johan Hedberg127178d2010-11-18 22:22:29 +02001287 struct hci_cp_remote_name_req *cp;
1288 struct hci_conn *conn;
1289
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001290 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001291
1292 /* If successful wait for the name req complete event before
1293 * checking for the need to do authentication */
1294 if (!status)
1295 return;
1296
1297 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1298 if (!cp)
1299 return;
1300
1301 hci_dev_lock(hdev);
1302
1303 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001304
1305 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1306 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1307
Johan Hedberg79c6c702011-04-28 11:28:55 -07001308 if (!conn)
1309 goto unlock;
1310
1311 if (!hci_outgoing_auth_needed(hdev, conn))
1312 goto unlock;
1313
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001314 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001315 struct hci_cp_auth_requested auth_cp;
1316
1317 auth_cp.handle = __cpu_to_le16(conn->handle);
1318 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1319 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001320 }
1321
Johan Hedberg79c6c702011-04-28 11:28:55 -07001322unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001323 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001324}
1325
Marcel Holtmann769be972008-07-14 20:13:49 +02001326static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1327{
1328 struct hci_cp_read_remote_features *cp;
1329 struct hci_conn *conn;
1330
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001331 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001332
1333 if (!status)
1334 return;
1335
1336 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1337 if (!cp)
1338 return;
1339
1340 hci_dev_lock(hdev);
1341
1342 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1343 if (conn) {
1344 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001345 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001346 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001347 }
1348 }
1349
1350 hci_dev_unlock(hdev);
1351}
1352
1353static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1354{
1355 struct hci_cp_read_remote_ext_features *cp;
1356 struct hci_conn *conn;
1357
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001358 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001359
1360 if (!status)
1361 return;
1362
1363 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1364 if (!cp)
1365 return;
1366
1367 hci_dev_lock(hdev);
1368
1369 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1370 if (conn) {
1371 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001372 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001373 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001374 }
1375 }
1376
1377 hci_dev_unlock(hdev);
1378}
1379
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001380static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1381{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001382 struct hci_cp_setup_sync_conn *cp;
1383 struct hci_conn *acl, *sco;
1384 __u16 handle;
1385
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001386 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001387
1388 if (!status)
1389 return;
1390
1391 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1392 if (!cp)
1393 return;
1394
1395 handle = __le16_to_cpu(cp->handle);
1396
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001397 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001398
1399 hci_dev_lock(hdev);
1400
1401 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001402 if (acl) {
1403 sco = acl->link;
1404 if (sco) {
1405 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001406
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001407 hci_proto_connect_cfm(sco, status);
1408 hci_conn_del(sco);
1409 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001410 }
1411
1412 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001413}
1414
1415static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1416{
1417 struct hci_cp_sniff_mode *cp;
1418 struct hci_conn *conn;
1419
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001420 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001421
1422 if (!status)
1423 return;
1424
1425 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1426 if (!cp)
1427 return;
1428
1429 hci_dev_lock(hdev);
1430
1431 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001432 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001433 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001434
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001435 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001436 hci_sco_setup(conn, status);
1437 }
1438
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001439 hci_dev_unlock(hdev);
1440}
1441
1442static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1443{
1444 struct hci_cp_exit_sniff_mode *cp;
1445 struct hci_conn *conn;
1446
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001447 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001448
1449 if (!status)
1450 return;
1451
1452 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1453 if (!cp)
1454 return;
1455
1456 hci_dev_lock(hdev);
1457
1458 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001459 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001460 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001461
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001462 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001463 hci_sco_setup(conn, status);
1464 }
1465
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001466 hci_dev_unlock(hdev);
1467}
1468
Johan Hedberg88c3df12012-02-09 14:27:38 +02001469static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1470{
1471 struct hci_cp_disconnect *cp;
1472 struct hci_conn *conn;
1473
1474 if (!status)
1475 return;
1476
1477 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1478 if (!cp)
1479 return;
1480
1481 hci_dev_lock(hdev);
1482
1483 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1484 if (conn)
1485 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001486 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001487
1488 hci_dev_unlock(hdev);
1489}
1490
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001491static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1492{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001493 struct hci_cp_create_phy_link *cp;
1494
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001495 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001496
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001497 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1498 if (!cp)
1499 return;
1500
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001501 hci_dev_lock(hdev);
1502
1503 if (status) {
1504 struct hci_conn *hcon;
1505
1506 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1507 if (hcon)
1508 hci_conn_del(hcon);
1509 } else {
1510 amp_write_remote_assoc(hdev, cp->phy_handle);
1511 }
1512
1513 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001514}
1515
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001516static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1517{
1518 struct hci_cp_accept_phy_link *cp;
1519
1520 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1521
1522 if (status)
1523 return;
1524
1525 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1526 if (!cp)
1527 return;
1528
1529 amp_write_remote_assoc(hdev, cp->phy_handle);
1530}
1531
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001532static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001533{
1534 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001535 struct discovery_state *discov = &hdev->discovery;
1536 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001537
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001538 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001539
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001540 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001541
1542 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1543 return;
1544
Andre Guedes3e13fa12013-03-27 20:04:56 -03001545 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1546 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1547
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001548 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001549 return;
1550
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001551 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001552
Andre Guedes343f9352012-02-17 20:39:37 -03001553 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001554 goto unlock;
1555
1556 if (list_empty(&discov->resolve)) {
1557 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1558 goto unlock;
1559 }
1560
1561 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1562 if (e && hci_resolve_name(hdev, e) == 0) {
1563 e->name_state = NAME_PENDING;
1564 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1565 } else {
1566 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1567 }
1568
1569unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001570 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001571}
1572
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001573static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001575 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001576 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 int num_rsp = *((__u8 *) skb->data);
1578
1579 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1580
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001581 if (!num_rsp)
1582 return;
1583
Andre Guedes1519cc12012-03-21 00:03:38 -03001584 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1585 return;
1586
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001588
Johan Hedberge17acd42011-03-30 23:57:16 +03001589 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001590 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001591
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592 bacpy(&data.bdaddr, &info->bdaddr);
1593 data.pscan_rep_mode = info->pscan_rep_mode;
1594 data.pscan_period_mode = info->pscan_period_mode;
1595 data.pscan_mode = info->pscan_mode;
1596 memcpy(data.dev_class, info->dev_class, 3);
1597 data.clock_offset = info->clock_offset;
1598 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001599 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001600
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001601 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001602 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001603 info->dev_class, 0, !name_known, ssp, NULL,
1604 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001606
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 hci_dev_unlock(hdev);
1608}
1609
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001610static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001612 struct hci_ev_conn_complete *ev = (void *) skb->data;
1613 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001615 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001616
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001618
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001619 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001620 if (!conn) {
1621 if (ev->link_type != SCO_LINK)
1622 goto unlock;
1623
1624 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1625 if (!conn)
1626 goto unlock;
1627
1628 conn->type = SCO_LINK;
1629 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001630
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001631 if (!ev->status) {
1632 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001633
1634 if (conn->type == ACL_LINK) {
1635 conn->state = BT_CONFIG;
1636 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001637
1638 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1639 !hci_find_link_key(hdev, &ev->bdaddr))
1640 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1641 else
1642 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001643 } else
1644 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001645
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001646 hci_conn_add_sysfs(conn);
1647
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001648 if (test_bit(HCI_AUTH, &hdev->flags))
1649 conn->link_mode |= HCI_LM_AUTH;
1650
1651 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1652 conn->link_mode |= HCI_LM_ENCRYPT;
1653
1654 /* Get remote features */
1655 if (conn->type == ACL_LINK) {
1656 struct hci_cp_read_remote_features cp;
1657 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001658 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001659 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001660 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001661
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001662 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001663 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001664 struct hci_cp_change_conn_ptype cp;
1665 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001666 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001667 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1668 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001669 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001670 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001671 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001672 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001673 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001674 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001675 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001676
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001677 if (conn->type == ACL_LINK)
1678 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001679
Marcel Holtmann769be972008-07-14 20:13:49 +02001680 if (ev->status) {
1681 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001682 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001683 } else if (ev->link_type != ACL_LINK)
1684 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001685
1686unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001688
1689 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690}
1691
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001692static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001694 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001696 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001698 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001699 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001701 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1702 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703
Szymon Janc138d22e2011-02-17 16:44:23 +01001704 if ((mask & HCI_LM_ACCEPT) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001705 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001707 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709
1710 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001711
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001712 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1713 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001714 memcpy(ie->data.dev_class, ev->dev_class, 3);
1715
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001716 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1717 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001719 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1720 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001721 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 hci_dev_unlock(hdev);
1723 return;
1724 }
1725 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001726
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001728
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 hci_dev_unlock(hdev);
1730
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001731 if (ev->link_type == ACL_LINK ||
1732 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001733 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001734 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001736 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001738 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1739 cp.role = 0x00; /* Become master */
1740 else
1741 cp.role = 0x01; /* Remain slave */
1742
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001743 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1744 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001745 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001746 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001747 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001748
1749 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001750 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001751
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001752 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1753 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1754 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001755 cp.content_format = cpu_to_le16(hdev->voice_setting);
1756 cp.retrans_effort = 0xff;
1757
1758 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001759 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001760 } else {
1761 conn->state = BT_CONNECT2;
1762 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001763 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764 } else {
1765 /* Connection rejected */
1766 struct hci_cp_reject_conn_req cp;
1767
1768 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001769 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001770 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771 }
1772}
1773
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001774static u8 hci_to_mgmt_reason(u8 err)
1775{
1776 switch (err) {
1777 case HCI_ERROR_CONNECTION_TIMEOUT:
1778 return MGMT_DEV_DISCONN_TIMEOUT;
1779 case HCI_ERROR_REMOTE_USER_TERM:
1780 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1781 case HCI_ERROR_REMOTE_POWER_OFF:
1782 return MGMT_DEV_DISCONN_REMOTE;
1783 case HCI_ERROR_LOCAL_HOST_TERM:
1784 return MGMT_DEV_DISCONN_LOCAL_HOST;
1785 default:
1786 return MGMT_DEV_DISCONN_UNKNOWN;
1787 }
1788}
1789
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001790static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001792 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001793 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001795 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 hci_dev_lock(hdev);
1798
Marcel Holtmann04837f62006-07-03 10:02:33 +02001799 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001800 if (!conn)
1801 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001802
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001803 if (ev->status == 0)
1804 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805
Johan Hedbergb644ba32012-01-17 21:48:47 +02001806 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001807 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001808 if (ev->status) {
Johan Hedberg88c3df12012-02-09 14:27:38 +02001809 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001810 conn->dst_type, ev->status);
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001811 } else {
1812 u8 reason = hci_to_mgmt_reason(ev->reason);
1813
Johan Hedbergafc747a2012-01-15 18:11:07 +02001814 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001815 conn->dst_type, reason);
1816 }
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001817 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001818
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001819 if (ev->status == 0) {
Johan Hedberg22102462013-10-05 12:01:06 +02001820 u8 type = conn->type;
1821
1822 if (type == ACL_LINK && conn->flush_key)
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301823 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001824 hci_proto_disconn_cfm(conn, ev->reason);
1825 hci_conn_del(conn);
Johan Hedberg22102462013-10-05 12:01:06 +02001826
1827 /* Re-enable advertising if necessary, since it might
1828 * have been disabled by the connection. From the
1829 * HCI_LE_Set_Advertise_Enable command description in
1830 * the core specification (v4.0):
1831 * "The Controller shall continue advertising until the Host
1832 * issues an LE_Set_Advertise_Enable command with
1833 * Advertising_Enable set to 0x00 (Advertising is disabled)
1834 * or until a connection is created or until the Advertising
1835 * is timed out due to Directed Advertising."
1836 */
1837 if (type == LE_LINK)
Marcel Holtmann5976e602013-10-06 04:08:14 -07001838 mgmt_reenable_advertising(hdev);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001839 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001840
1841unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842 hci_dev_unlock(hdev);
1843}
1844
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001845static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001846{
1847 struct hci_ev_auth_complete *ev = (void *) skb->data;
1848 struct hci_conn *conn;
1849
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001850 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001851
1852 hci_dev_lock(hdev);
1853
1854 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001855 if (!conn)
1856 goto unlock;
1857
1858 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001859 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001860 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001861 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001862 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001863 conn->link_mode |= HCI_LM_AUTH;
1864 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001865 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001866 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001867 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001868 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001869 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001870
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001871 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1872 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001873
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001874 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001875 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001876 struct hci_cp_set_conn_encrypt cp;
1877 cp.handle = ev->handle;
1878 cp.encrypt = 0x01;
1879 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001880 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001881 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001882 conn->state = BT_CONNECTED;
1883 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001884 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001885 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001886 } else {
1887 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001888
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001889 hci_conn_hold(conn);
1890 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001891 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001892 }
1893
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001894 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001895 if (!ev->status) {
1896 struct hci_cp_set_conn_encrypt cp;
1897 cp.handle = ev->handle;
1898 cp.encrypt = 0x01;
1899 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001900 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001901 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001902 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001903 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001904 }
1905 }
1906
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001907unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001908 hci_dev_unlock(hdev);
1909}
1910
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001911static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001912{
Johan Hedberg127178d2010-11-18 22:22:29 +02001913 struct hci_ev_remote_name *ev = (void *) skb->data;
1914 struct hci_conn *conn;
1915
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001916 BT_DBG("%s", hdev->name);
1917
1918 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001919
1920 hci_dev_lock(hdev);
1921
1922 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001923
1924 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1925 goto check_auth;
1926
1927 if (ev->status == 0)
1928 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001929 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001930 else
1931 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1932
1933check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001934 if (!conn)
1935 goto unlock;
1936
1937 if (!hci_outgoing_auth_needed(hdev, conn))
1938 goto unlock;
1939
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001940 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001941 struct hci_cp_auth_requested cp;
1942 cp.handle = __cpu_to_le16(conn->handle);
1943 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1944 }
1945
Johan Hedberg79c6c702011-04-28 11:28:55 -07001946unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001947 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001948}
1949
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001950static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001951{
1952 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1953 struct hci_conn *conn;
1954
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001955 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001956
1957 hci_dev_lock(hdev);
1958
1959 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1960 if (conn) {
1961 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001962 if (ev->encrypt) {
1963 /* Encryption implies authentication */
1964 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001965 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001966 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001967 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001968 conn->link_mode &= ~HCI_LM_ENCRYPT;
1969 }
1970
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001971 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001972
Gustavo Padovana7d77232012-05-13 03:20:07 -03001973 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03001974 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02001975 hci_conn_drop(conn);
Gustavo Padovana7d77232012-05-13 03:20:07 -03001976 goto unlock;
1977 }
1978
Marcel Holtmannf8558552008-07-14 20:13:49 +02001979 if (conn->state == BT_CONFIG) {
1980 if (!ev->status)
1981 conn->state = BT_CONNECTED;
1982
1983 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001984 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001985 } else
1986 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001987 }
1988
Gustavo Padovana7d77232012-05-13 03:20:07 -03001989unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001990 hci_dev_unlock(hdev);
1991}
1992
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001993static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
1994 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001995{
1996 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1997 struct hci_conn *conn;
1998
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001999 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002000
2001 hci_dev_lock(hdev);
2002
2003 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2004 if (conn) {
2005 if (!ev->status)
2006 conn->link_mode |= HCI_LM_SECURE;
2007
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002008 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002009
2010 hci_key_change_cfm(conn, ev->status);
2011 }
2012
2013 hci_dev_unlock(hdev);
2014}
2015
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002016static void hci_remote_features_evt(struct hci_dev *hdev,
2017 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002018{
2019 struct hci_ev_remote_features *ev = (void *) skb->data;
2020 struct hci_conn *conn;
2021
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002022 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002023
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002024 hci_dev_lock(hdev);
2025
2026 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002027 if (!conn)
2028 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002029
Johan Hedbergccd556f2010-11-10 17:11:51 +02002030 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002031 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002032
2033 if (conn->state != BT_CONFIG)
2034 goto unlock;
2035
2036 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2037 struct hci_cp_read_remote_ext_features cp;
2038 cp.handle = ev->handle;
2039 cp.page = 0x01;
2040 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002041 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002042 goto unlock;
2043 }
2044
Johan Hedberg671267b2012-05-12 16:11:50 -03002045 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002046 struct hci_cp_remote_name_req cp;
2047 memset(&cp, 0, sizeof(cp));
2048 bacpy(&cp.bdaddr, &conn->dst);
2049 cp.pscan_rep_mode = 0x02;
2050 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002051 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2052 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002053 conn->dst_type, 0, NULL, 0,
2054 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002055
Johan Hedberg127178d2010-11-18 22:22:29 +02002056 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002057 conn->state = BT_CONNECTED;
2058 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002059 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002060 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002061
Johan Hedbergccd556f2010-11-10 17:11:51 +02002062unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002063 hci_dev_unlock(hdev);
2064}
2065
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002066static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002067{
2068 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002069 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002070 __u16 opcode;
2071
2072 skb_pull(skb, sizeof(*ev));
2073
2074 opcode = __le16_to_cpu(ev->opcode);
2075
2076 switch (opcode) {
2077 case HCI_OP_INQUIRY_CANCEL:
2078 hci_cc_inquiry_cancel(hdev, skb);
2079 break;
2080
Andre Guedes4d934832012-03-21 00:03:35 -03002081 case HCI_OP_PERIODIC_INQ:
2082 hci_cc_periodic_inq(hdev, skb);
2083 break;
2084
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002085 case HCI_OP_EXIT_PERIODIC_INQ:
2086 hci_cc_exit_periodic_inq(hdev, skb);
2087 break;
2088
2089 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2090 hci_cc_remote_name_req_cancel(hdev, skb);
2091 break;
2092
2093 case HCI_OP_ROLE_DISCOVERY:
2094 hci_cc_role_discovery(hdev, skb);
2095 break;
2096
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002097 case HCI_OP_READ_LINK_POLICY:
2098 hci_cc_read_link_policy(hdev, skb);
2099 break;
2100
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002101 case HCI_OP_WRITE_LINK_POLICY:
2102 hci_cc_write_link_policy(hdev, skb);
2103 break;
2104
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002105 case HCI_OP_READ_DEF_LINK_POLICY:
2106 hci_cc_read_def_link_policy(hdev, skb);
2107 break;
2108
2109 case HCI_OP_WRITE_DEF_LINK_POLICY:
2110 hci_cc_write_def_link_policy(hdev, skb);
2111 break;
2112
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002113 case HCI_OP_RESET:
2114 hci_cc_reset(hdev, skb);
2115 break;
2116
2117 case HCI_OP_WRITE_LOCAL_NAME:
2118 hci_cc_write_local_name(hdev, skb);
2119 break;
2120
2121 case HCI_OP_READ_LOCAL_NAME:
2122 hci_cc_read_local_name(hdev, skb);
2123 break;
2124
2125 case HCI_OP_WRITE_AUTH_ENABLE:
2126 hci_cc_write_auth_enable(hdev, skb);
2127 break;
2128
2129 case HCI_OP_WRITE_ENCRYPT_MODE:
2130 hci_cc_write_encrypt_mode(hdev, skb);
2131 break;
2132
2133 case HCI_OP_WRITE_SCAN_ENABLE:
2134 hci_cc_write_scan_enable(hdev, skb);
2135 break;
2136
2137 case HCI_OP_READ_CLASS_OF_DEV:
2138 hci_cc_read_class_of_dev(hdev, skb);
2139 break;
2140
2141 case HCI_OP_WRITE_CLASS_OF_DEV:
2142 hci_cc_write_class_of_dev(hdev, skb);
2143 break;
2144
2145 case HCI_OP_READ_VOICE_SETTING:
2146 hci_cc_read_voice_setting(hdev, skb);
2147 break;
2148
2149 case HCI_OP_WRITE_VOICE_SETTING:
2150 hci_cc_write_voice_setting(hdev, skb);
2151 break;
2152
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002153 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2154 hci_cc_read_num_supported_iac(hdev, skb);
2155 break;
2156
Marcel Holtmann333140b2008-07-14 20:13:48 +02002157 case HCI_OP_WRITE_SSP_MODE:
2158 hci_cc_write_ssp_mode(hdev, skb);
2159 break;
2160
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002161 case HCI_OP_READ_LOCAL_VERSION:
2162 hci_cc_read_local_version(hdev, skb);
2163 break;
2164
2165 case HCI_OP_READ_LOCAL_COMMANDS:
2166 hci_cc_read_local_commands(hdev, skb);
2167 break;
2168
2169 case HCI_OP_READ_LOCAL_FEATURES:
2170 hci_cc_read_local_features(hdev, skb);
2171 break;
2172
Andre Guedes971e3a42011-06-30 19:20:52 -03002173 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2174 hci_cc_read_local_ext_features(hdev, skb);
2175 break;
2176
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002177 case HCI_OP_READ_BUFFER_SIZE:
2178 hci_cc_read_buffer_size(hdev, skb);
2179 break;
2180
2181 case HCI_OP_READ_BD_ADDR:
2182 hci_cc_read_bd_addr(hdev, skb);
2183 break;
2184
Johan Hedbergf332ec62013-03-15 17:07:11 -05002185 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2186 hci_cc_read_page_scan_activity(hdev, skb);
2187 break;
2188
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002189 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2190 hci_cc_write_page_scan_activity(hdev, skb);
2191 break;
2192
Johan Hedbergf332ec62013-03-15 17:07:11 -05002193 case HCI_OP_READ_PAGE_SCAN_TYPE:
2194 hci_cc_read_page_scan_type(hdev, skb);
2195 break;
2196
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002197 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2198 hci_cc_write_page_scan_type(hdev, skb);
2199 break;
2200
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002201 case HCI_OP_READ_DATA_BLOCK_SIZE:
2202 hci_cc_read_data_block_size(hdev, skb);
2203 break;
2204
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002205 case HCI_OP_READ_FLOW_CONTROL_MODE:
2206 hci_cc_read_flow_control_mode(hdev, skb);
2207 break;
2208
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002209 case HCI_OP_READ_LOCAL_AMP_INFO:
2210 hci_cc_read_local_amp_info(hdev, skb);
2211 break;
2212
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002213 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2214 hci_cc_read_local_amp_assoc(hdev, skb);
2215 break;
2216
Johan Hedbergd5859e22011-01-25 01:19:58 +02002217 case HCI_OP_READ_INQ_RSP_TX_POWER:
2218 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2219 break;
2220
Johan Hedberg980e1a52011-01-22 06:10:07 +02002221 case HCI_OP_PIN_CODE_REPLY:
2222 hci_cc_pin_code_reply(hdev, skb);
2223 break;
2224
2225 case HCI_OP_PIN_CODE_NEG_REPLY:
2226 hci_cc_pin_code_neg_reply(hdev, skb);
2227 break;
2228
Szymon Jancc35938b2011-03-22 13:12:21 +01002229 case HCI_OP_READ_LOCAL_OOB_DATA:
2230 hci_cc_read_local_oob_data_reply(hdev, skb);
2231 break;
2232
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002233 case HCI_OP_LE_READ_BUFFER_SIZE:
2234 hci_cc_le_read_buffer_size(hdev, skb);
2235 break;
2236
Johan Hedberg60e77322013-01-22 14:01:59 +02002237 case HCI_OP_LE_READ_LOCAL_FEATURES:
2238 hci_cc_le_read_local_features(hdev, skb);
2239 break;
2240
Johan Hedberg8fa19092012-10-19 20:57:49 +03002241 case HCI_OP_LE_READ_ADV_TX_POWER:
2242 hci_cc_le_read_adv_tx_power(hdev, skb);
2243 break;
2244
Johan Hedberga5c29682011-02-19 12:05:57 -03002245 case HCI_OP_USER_CONFIRM_REPLY:
2246 hci_cc_user_confirm_reply(hdev, skb);
2247 break;
2248
2249 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2250 hci_cc_user_confirm_neg_reply(hdev, skb);
2251 break;
2252
Brian Gix1143d452011-11-23 08:28:34 -08002253 case HCI_OP_USER_PASSKEY_REPLY:
2254 hci_cc_user_passkey_reply(hdev, skb);
2255 break;
2256
2257 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2258 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002259 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002260
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002261 case HCI_OP_LE_SET_ADV_ENABLE:
2262 hci_cc_le_set_adv_enable(hdev, skb);
2263 break;
2264
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002265 case HCI_OP_LE_SET_SCAN_ENABLE:
2266 hci_cc_le_set_scan_enable(hdev, skb);
2267 break;
2268
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002269 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2270 hci_cc_le_read_white_list_size(hdev, skb);
2271 break;
2272
Johan Hedberg9b008c02013-01-22 14:02:01 +02002273 case HCI_OP_LE_READ_SUPPORTED_STATES:
2274 hci_cc_le_read_supported_states(hdev, skb);
2275 break;
2276
Andre Guedesf9b49302011-06-30 19:20:53 -03002277 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2278 hci_cc_write_le_host_supported(hdev, skb);
2279 break;
2280
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002281 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2282 hci_cc_write_remote_amp_assoc(hdev, skb);
2283 break;
2284
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002285 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002286 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002287 break;
2288 }
2289
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002290 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002291 del_timer(&hdev->cmd_timer);
2292
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002293 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002294
Szymon Jancdbccd792012-12-11 08:51:19 +01002295 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002296 atomic_set(&hdev->cmd_cnt, 1);
2297 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002298 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002299 }
2300}
2301
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002302static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002303{
2304 struct hci_ev_cmd_status *ev = (void *) skb->data;
2305 __u16 opcode;
2306
2307 skb_pull(skb, sizeof(*ev));
2308
2309 opcode = __le16_to_cpu(ev->opcode);
2310
2311 switch (opcode) {
2312 case HCI_OP_INQUIRY:
2313 hci_cs_inquiry(hdev, ev->status);
2314 break;
2315
2316 case HCI_OP_CREATE_CONN:
2317 hci_cs_create_conn(hdev, ev->status);
2318 break;
2319
2320 case HCI_OP_ADD_SCO:
2321 hci_cs_add_sco(hdev, ev->status);
2322 break;
2323
Marcel Holtmannf8558552008-07-14 20:13:49 +02002324 case HCI_OP_AUTH_REQUESTED:
2325 hci_cs_auth_requested(hdev, ev->status);
2326 break;
2327
2328 case HCI_OP_SET_CONN_ENCRYPT:
2329 hci_cs_set_conn_encrypt(hdev, ev->status);
2330 break;
2331
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002332 case HCI_OP_REMOTE_NAME_REQ:
2333 hci_cs_remote_name_req(hdev, ev->status);
2334 break;
2335
Marcel Holtmann769be972008-07-14 20:13:49 +02002336 case HCI_OP_READ_REMOTE_FEATURES:
2337 hci_cs_read_remote_features(hdev, ev->status);
2338 break;
2339
2340 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2341 hci_cs_read_remote_ext_features(hdev, ev->status);
2342 break;
2343
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002344 case HCI_OP_SETUP_SYNC_CONN:
2345 hci_cs_setup_sync_conn(hdev, ev->status);
2346 break;
2347
2348 case HCI_OP_SNIFF_MODE:
2349 hci_cs_sniff_mode(hdev, ev->status);
2350 break;
2351
2352 case HCI_OP_EXIT_SNIFF_MODE:
2353 hci_cs_exit_sniff_mode(hdev, ev->status);
2354 break;
2355
Johan Hedberg8962ee72011-01-20 12:40:27 +02002356 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002357 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002358 break;
2359
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002360 case HCI_OP_CREATE_PHY_LINK:
2361 hci_cs_create_phylink(hdev, ev->status);
2362 break;
2363
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002364 case HCI_OP_ACCEPT_PHY_LINK:
2365 hci_cs_accept_phylink(hdev, ev->status);
2366 break;
2367
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002368 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002369 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002370 break;
2371 }
2372
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002373 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002374 del_timer(&hdev->cmd_timer);
2375
Johan Hedberg02350a72013-04-03 21:50:29 +03002376 if (ev->status ||
2377 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2378 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002379
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002380 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002381 atomic_set(&hdev->cmd_cnt, 1);
2382 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002383 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002384 }
2385}
2386
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002387static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002388{
2389 struct hci_ev_role_change *ev = (void *) skb->data;
2390 struct hci_conn *conn;
2391
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002392 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002393
2394 hci_dev_lock(hdev);
2395
2396 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2397 if (conn) {
2398 if (!ev->status) {
2399 if (ev->role)
2400 conn->link_mode &= ~HCI_LM_MASTER;
2401 else
2402 conn->link_mode |= HCI_LM_MASTER;
2403 }
2404
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002405 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002406
2407 hci_role_switch_cfm(conn, ev->status, ev->role);
2408 }
2409
2410 hci_dev_unlock(hdev);
2411}
2412
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002413static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002414{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002415 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002416 int i;
2417
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002418 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2419 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2420 return;
2421 }
2422
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002423 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002424 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002425 BT_DBG("%s bad parameters", hdev->name);
2426 return;
2427 }
2428
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002429 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2430
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002431 for (i = 0; i < ev->num_hndl; i++) {
2432 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002433 struct hci_conn *conn;
2434 __u16 handle, count;
2435
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002436 handle = __le16_to_cpu(info->handle);
2437 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002438
2439 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002440 if (!conn)
2441 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002442
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002443 conn->sent -= count;
2444
2445 switch (conn->type) {
2446 case ACL_LINK:
2447 hdev->acl_cnt += count;
2448 if (hdev->acl_cnt > hdev->acl_pkts)
2449 hdev->acl_cnt = hdev->acl_pkts;
2450 break;
2451
2452 case LE_LINK:
2453 if (hdev->le_pkts) {
2454 hdev->le_cnt += count;
2455 if (hdev->le_cnt > hdev->le_pkts)
2456 hdev->le_cnt = hdev->le_pkts;
2457 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002458 hdev->acl_cnt += count;
2459 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002460 hdev->acl_cnt = hdev->acl_pkts;
2461 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002462 break;
2463
2464 case SCO_LINK:
2465 hdev->sco_cnt += count;
2466 if (hdev->sco_cnt > hdev->sco_pkts)
2467 hdev->sco_cnt = hdev->sco_pkts;
2468 break;
2469
2470 default:
2471 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2472 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002473 }
2474 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002475
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002476 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002477}
2478
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002479static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2480 __u16 handle)
2481{
2482 struct hci_chan *chan;
2483
2484 switch (hdev->dev_type) {
2485 case HCI_BREDR:
2486 return hci_conn_hash_lookup_handle(hdev, handle);
2487 case HCI_AMP:
2488 chan = hci_chan_lookup_handle(hdev, handle);
2489 if (chan)
2490 return chan->conn;
2491 break;
2492 default:
2493 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2494 break;
2495 }
2496
2497 return NULL;
2498}
2499
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002500static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002501{
2502 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2503 int i;
2504
2505 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2506 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2507 return;
2508 }
2509
2510 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002511 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002512 BT_DBG("%s bad parameters", hdev->name);
2513 return;
2514 }
2515
2516 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002517 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002518
2519 for (i = 0; i < ev->num_hndl; i++) {
2520 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002521 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002522 __u16 handle, block_count;
2523
2524 handle = __le16_to_cpu(info->handle);
2525 block_count = __le16_to_cpu(info->blocks);
2526
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002527 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002528 if (!conn)
2529 continue;
2530
2531 conn->sent -= block_count;
2532
2533 switch (conn->type) {
2534 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002535 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002536 hdev->block_cnt += block_count;
2537 if (hdev->block_cnt > hdev->num_blocks)
2538 hdev->block_cnt = hdev->num_blocks;
2539 break;
2540
2541 default:
2542 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2543 break;
2544 }
2545 }
2546
2547 queue_work(hdev->workqueue, &hdev->tx_work);
2548}
2549
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002550static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002552 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002553 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002554
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002555 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002556
2557 hci_dev_lock(hdev);
2558
Marcel Holtmann04837f62006-07-03 10:02:33 +02002559 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2560 if (conn) {
2561 conn->mode = ev->mode;
2562 conn->interval = __le16_to_cpu(ev->interval);
2563
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002564 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2565 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002566 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002567 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002568 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002569 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002570 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002571
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002572 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002573 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002574 }
2575
2576 hci_dev_unlock(hdev);
2577}
2578
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002579static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002580{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002581 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2582 struct hci_conn *conn;
2583
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002584 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002585
2586 hci_dev_lock(hdev);
2587
2588 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002589 if (!conn)
2590 goto unlock;
2591
2592 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002593 hci_conn_hold(conn);
2594 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002595 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002596 }
2597
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002598 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002599 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002600 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002601 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002602 u8 secure;
2603
2604 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2605 secure = 1;
2606 else
2607 secure = 0;
2608
Johan Hedberg744cf192011-11-08 20:40:14 +02002609 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002610 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002611
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002612unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002613 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002614}
2615
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002616static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002617{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002618 struct hci_ev_link_key_req *ev = (void *) skb->data;
2619 struct hci_cp_link_key_reply cp;
2620 struct hci_conn *conn;
2621 struct link_key *key;
2622
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002623 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002624
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002625 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002626 return;
2627
2628 hci_dev_lock(hdev);
2629
2630 key = hci_find_link_key(hdev, &ev->bdaddr);
2631 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002632 BT_DBG("%s link key not found for %pMR", hdev->name,
2633 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002634 goto not_found;
2635 }
2636
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002637 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2638 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002639
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002640 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002641 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002642 BT_DBG("%s ignoring debug key", hdev->name);
2643 goto not_found;
2644 }
2645
2646 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002647 if (conn) {
2648 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002649 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002650 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2651 goto not_found;
2652 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002653
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002654 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002655 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002656 BT_DBG("%s ignoring key unauthenticated for high security",
2657 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002658 goto not_found;
2659 }
2660
2661 conn->key_type = key->type;
2662 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002663 }
2664
2665 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002666 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002667
2668 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2669
2670 hci_dev_unlock(hdev);
2671
2672 return;
2673
2674not_found:
2675 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2676 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002677}
2678
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002679static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002680{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002681 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2682 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002683 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002684
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002685 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002686
2687 hci_dev_lock(hdev);
2688
2689 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2690 if (conn) {
2691 hci_conn_hold(conn);
2692 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002693 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002694
2695 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2696 conn->key_type = ev->key_type;
2697
David Herrmann76a68ba2013-04-06 20:28:37 +02002698 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002699 }
2700
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002701 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002702 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002703 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002704
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002705 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706}
2707
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002708static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002709{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002710 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002711 struct hci_conn *conn;
2712
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002713 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002714
2715 hci_dev_lock(hdev);
2716
2717 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002718 if (conn && !ev->status) {
2719 struct inquiry_entry *ie;
2720
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002721 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2722 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723 ie->data.clock_offset = ev->clock_offset;
2724 ie->timestamp = jiffies;
2725 }
2726 }
2727
2728 hci_dev_unlock(hdev);
2729}
2730
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002731static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002732{
2733 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2734 struct hci_conn *conn;
2735
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002736 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002737
2738 hci_dev_lock(hdev);
2739
2740 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2741 if (conn && !ev->status)
2742 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2743
2744 hci_dev_unlock(hdev);
2745}
2746
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002747static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002748{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002749 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002750 struct inquiry_entry *ie;
2751
2752 BT_DBG("%s", hdev->name);
2753
2754 hci_dev_lock(hdev);
2755
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002756 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2757 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002758 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2759 ie->timestamp = jiffies;
2760 }
2761
2762 hci_dev_unlock(hdev);
2763}
2764
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002765static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2766 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002767{
2768 struct inquiry_data data;
2769 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002770 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002771
2772 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2773
2774 if (!num_rsp)
2775 return;
2776
Andre Guedes1519cc12012-03-21 00:03:38 -03002777 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2778 return;
2779
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002780 hci_dev_lock(hdev);
2781
2782 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002783 struct inquiry_info_with_rssi_and_pscan_mode *info;
2784 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002785
Johan Hedberge17acd42011-03-30 23:57:16 +03002786 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002787 bacpy(&data.bdaddr, &info->bdaddr);
2788 data.pscan_rep_mode = info->pscan_rep_mode;
2789 data.pscan_period_mode = info->pscan_period_mode;
2790 data.pscan_mode = info->pscan_mode;
2791 memcpy(data.dev_class, info->dev_class, 3);
2792 data.clock_offset = info->clock_offset;
2793 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002794 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002795
2796 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002797 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002798 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002799 info->dev_class, info->rssi,
2800 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002801 }
2802 } else {
2803 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2804
Johan Hedberge17acd42011-03-30 23:57:16 +03002805 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002806 bacpy(&data.bdaddr, &info->bdaddr);
2807 data.pscan_rep_mode = info->pscan_rep_mode;
2808 data.pscan_period_mode = info->pscan_period_mode;
2809 data.pscan_mode = 0x00;
2810 memcpy(data.dev_class, info->dev_class, 3);
2811 data.clock_offset = info->clock_offset;
2812 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002813 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002814 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002815 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002816 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002817 info->dev_class, info->rssi,
2818 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002819 }
2820 }
2821
2822 hci_dev_unlock(hdev);
2823}
2824
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002825static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2826 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002827{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002828 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2829 struct hci_conn *conn;
2830
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002831 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002832
Marcel Holtmann41a96212008-07-14 20:13:48 +02002833 hci_dev_lock(hdev);
2834
2835 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002836 if (!conn)
2837 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002838
Johan Hedbergcad718e2013-04-17 15:00:51 +03002839 if (ev->page < HCI_MAX_PAGES)
2840 memcpy(conn->features[ev->page], ev->features, 8);
2841
Johan Hedbergccd556f2010-11-10 17:11:51 +02002842 if (!ev->status && ev->page == 0x01) {
2843 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002844
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002845 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2846 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002847 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002848
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302849 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002850 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302851 } else {
2852 /* It is mandatory by the Bluetooth specification that
2853 * Extended Inquiry Results are only used when Secure
2854 * Simple Pairing is enabled, but some devices violate
2855 * this.
2856 *
2857 * To make these devices work, the internal SSP
2858 * enabled flag needs to be cleared if the remote host
2859 * features do not indicate SSP support */
2860 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2861 }
Marcel Holtmann41a96212008-07-14 20:13:48 +02002862 }
2863
Johan Hedbergccd556f2010-11-10 17:11:51 +02002864 if (conn->state != BT_CONFIG)
2865 goto unlock;
2866
Johan Hedberg671267b2012-05-12 16:11:50 -03002867 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002868 struct hci_cp_remote_name_req cp;
2869 memset(&cp, 0, sizeof(cp));
2870 bacpy(&cp.bdaddr, &conn->dst);
2871 cp.pscan_rep_mode = 0x02;
2872 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002873 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2874 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002875 conn->dst_type, 0, NULL, 0,
2876 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002877
Johan Hedberg127178d2010-11-18 22:22:29 +02002878 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002879 conn->state = BT_CONNECTED;
2880 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002881 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002882 }
2883
2884unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002885 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002886}
2887
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002888static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2889 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002890{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002891 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2892 struct hci_conn *conn;
2893
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002894 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002895
2896 hci_dev_lock(hdev);
2897
2898 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002899 if (!conn) {
2900 if (ev->link_type == ESCO_LINK)
2901 goto unlock;
2902
2903 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2904 if (!conn)
2905 goto unlock;
2906
2907 conn->type = SCO_LINK;
2908 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002909
Marcel Holtmann732547f2009-04-19 19:14:14 +02002910 switch (ev->status) {
2911 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002912 conn->handle = __le16_to_cpu(ev->handle);
2913 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002914
2915 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002916 break;
2917
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02002918 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05002919 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002920 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002921 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002922 case 0x1f: /* Unspecified error */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002923 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02002924 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2925 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002926 if (hci_setup_sync(conn, conn->link->handle))
2927 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002928 }
2929 /* fall through */
2930
2931 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002932 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002933 break;
2934 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002935
2936 hci_proto_connect_cfm(conn, ev->status);
2937 if (ev->status)
2938 hci_conn_del(conn);
2939
2940unlock:
2941 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002942}
2943
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002944static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
2945 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002946{
2947 struct inquiry_data data;
2948 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2949 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302950 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002951
2952 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2953
2954 if (!num_rsp)
2955 return;
2956
Andre Guedes1519cc12012-03-21 00:03:38 -03002957 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2958 return;
2959
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002960 hci_dev_lock(hdev);
2961
Johan Hedberge17acd42011-03-30 23:57:16 +03002962 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002963 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002964
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002965 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002966 data.pscan_rep_mode = info->pscan_rep_mode;
2967 data.pscan_period_mode = info->pscan_period_mode;
2968 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002969 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002970 data.clock_offset = info->clock_offset;
2971 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002972 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002973
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002974 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002975 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002976 sizeof(info->data),
2977 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002978 else
2979 name_known = true;
2980
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002981 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002982 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302983 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02002984 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002985 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302986 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002987 }
2988
2989 hci_dev_unlock(hdev);
2990}
2991
Johan Hedberg1c2e0042012-06-08 23:31:13 +08002992static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
2993 struct sk_buff *skb)
2994{
2995 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
2996 struct hci_conn *conn;
2997
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002998 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08002999 __le16_to_cpu(ev->handle));
3000
3001 hci_dev_lock(hdev);
3002
3003 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3004 if (!conn)
3005 goto unlock;
3006
3007 if (!ev->status)
3008 conn->sec_level = conn->pending_sec_level;
3009
3010 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3011
3012 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003013 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003014 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003015 goto unlock;
3016 }
3017
3018 if (conn->state == BT_CONFIG) {
3019 if (!ev->status)
3020 conn->state = BT_CONNECTED;
3021
3022 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003023 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003024 } else {
3025 hci_auth_cfm(conn, ev->status);
3026
3027 hci_conn_hold(conn);
3028 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003029 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003030 }
3031
3032unlock:
3033 hci_dev_unlock(hdev);
3034}
3035
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003036static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003037{
3038 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003039 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3040 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003041 /* If both remote and local IO capabilities allow MITM
3042 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003043 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3044 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3045 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003046 else
Mikel Astizacabae92013-06-28 10:56:28 +02003047 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003048 }
3049
3050 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003051 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3052 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003053 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003054
3055 return conn->auth_type;
3056}
3057
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003058static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003059{
3060 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3061 struct hci_conn *conn;
3062
3063 BT_DBG("%s", hdev->name);
3064
3065 hci_dev_lock(hdev);
3066
3067 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003068 if (!conn)
3069 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003070
Johan Hedberg03b555e2011-01-04 15:40:05 +02003071 hci_conn_hold(conn);
3072
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003073 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003074 goto unlock;
3075
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003076 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003077 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003078 struct hci_cp_io_capability_reply cp;
3079
3080 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303081 /* Change the IO capability from KeyboardDisplay
3082 * to DisplayYesNo as it is not supported by BT spec. */
3083 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003084 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003085 conn->auth_type = hci_get_auth_req(conn);
3086 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003087
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003088 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3089 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003090 cp.oob_data = 0x01;
3091 else
3092 cp.oob_data = 0x00;
3093
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003094 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003095 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003096 } else {
3097 struct hci_cp_io_capability_neg_reply cp;
3098
3099 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003100 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003101
3102 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003103 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003104 }
3105
3106unlock:
3107 hci_dev_unlock(hdev);
3108}
3109
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003110static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003111{
3112 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3113 struct hci_conn *conn;
3114
3115 BT_DBG("%s", hdev->name);
3116
3117 hci_dev_lock(hdev);
3118
3119 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3120 if (!conn)
3121 goto unlock;
3122
Johan Hedberg03b555e2011-01-04 15:40:05 +02003123 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003124 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003125 if (ev->oob_data)
3126 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003127
3128unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003129 hci_dev_unlock(hdev);
3130}
3131
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003132static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3133 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003134{
3135 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003136 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003137 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003138
3139 BT_DBG("%s", hdev->name);
3140
3141 hci_dev_lock(hdev);
3142
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003143 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003144 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003145
Johan Hedberg7a828902011-04-28 11:28:53 -07003146 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3147 if (!conn)
3148 goto unlock;
3149
3150 loc_mitm = (conn->auth_type & 0x01);
3151 rem_mitm = (conn->remote_auth & 0x01);
3152
3153 /* If we require MITM but the remote device can't provide that
3154 * (it has NoInputNoOutput) then reject the confirmation
3155 * request. The only exception is when we're dedicated bonding
3156 * initiators (connect_cfm_cb set) since then we always have the MITM
3157 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003158 if (!conn->connect_cfm_cb && loc_mitm &&
3159 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003160 BT_DBG("Rejecting request: remote device can't provide MITM");
3161 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003162 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003163 goto unlock;
3164 }
3165
3166 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003167 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3168 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003169
3170 /* If we're not the initiators request authorization to
3171 * proceed from user space (mgmt_user_confirm with
3172 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003173 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003174 BT_DBG("Confirming auto-accept as acceptor");
3175 confirm_hint = 1;
3176 goto confirm;
3177 }
3178
Johan Hedberg9f616562011-04-28 11:28:54 -07003179 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003180 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003181
3182 if (hdev->auto_accept_delay > 0) {
3183 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3184 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3185 goto unlock;
3186 }
3187
Johan Hedberg7a828902011-04-28 11:28:53 -07003188 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003189 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003190 goto unlock;
3191 }
3192
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003193confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003194 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003195 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003196
3197unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003198 hci_dev_unlock(hdev);
3199}
3200
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003201static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3202 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003203{
3204 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3205
3206 BT_DBG("%s", hdev->name);
3207
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003208 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003209 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003210}
3211
Johan Hedberg92a25252012-09-06 18:39:26 +03003212static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3213 struct sk_buff *skb)
3214{
3215 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3216 struct hci_conn *conn;
3217
3218 BT_DBG("%s", hdev->name);
3219
3220 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3221 if (!conn)
3222 return;
3223
3224 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3225 conn->passkey_entered = 0;
3226
3227 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3228 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3229 conn->dst_type, conn->passkey_notify,
3230 conn->passkey_entered);
3231}
3232
3233static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3234{
3235 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3236 struct hci_conn *conn;
3237
3238 BT_DBG("%s", hdev->name);
3239
3240 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3241 if (!conn)
3242 return;
3243
3244 switch (ev->type) {
3245 case HCI_KEYPRESS_STARTED:
3246 conn->passkey_entered = 0;
3247 return;
3248
3249 case HCI_KEYPRESS_ENTERED:
3250 conn->passkey_entered++;
3251 break;
3252
3253 case HCI_KEYPRESS_ERASED:
3254 conn->passkey_entered--;
3255 break;
3256
3257 case HCI_KEYPRESS_CLEARED:
3258 conn->passkey_entered = 0;
3259 break;
3260
3261 case HCI_KEYPRESS_COMPLETED:
3262 return;
3263 }
3264
3265 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3266 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3267 conn->dst_type, conn->passkey_notify,
3268 conn->passkey_entered);
3269}
3270
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003271static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3272 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003273{
3274 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3275 struct hci_conn *conn;
3276
3277 BT_DBG("%s", hdev->name);
3278
3279 hci_dev_lock(hdev);
3280
3281 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003282 if (!conn)
3283 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003284
Johan Hedberg2a611692011-02-19 12:06:00 -03003285 /* To avoid duplicate auth_failed events to user space we check
3286 * the HCI_CONN_AUTH_PEND flag which will be set if we
3287 * initiated the authentication. A traditional auth_complete
3288 * event gets always produced as initiator and is also mapped to
3289 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003290 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003291 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003292 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003293
David Herrmann76a68ba2013-04-06 20:28:37 +02003294 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003295
3296unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003297 hci_dev_unlock(hdev);
3298}
3299
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003300static void hci_remote_host_features_evt(struct hci_dev *hdev,
3301 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003302{
3303 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3304 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003305 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003306
3307 BT_DBG("%s", hdev->name);
3308
3309 hci_dev_lock(hdev);
3310
Johan Hedbergcad718e2013-04-17 15:00:51 +03003311 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3312 if (conn)
3313 memcpy(conn->features[1], ev->features, 8);
3314
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003315 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3316 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003317 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003318
3319 hci_dev_unlock(hdev);
3320}
3321
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003322static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3323 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003324{
3325 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3326 struct oob_data *data;
3327
3328 BT_DBG("%s", hdev->name);
3329
3330 hci_dev_lock(hdev);
3331
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003332 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003333 goto unlock;
3334
Szymon Janc2763eda2011-03-22 13:12:22 +01003335 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3336 if (data) {
3337 struct hci_cp_remote_oob_data_reply cp;
3338
3339 bacpy(&cp.bdaddr, &ev->bdaddr);
3340 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3341 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3342
3343 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003344 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003345 } else {
3346 struct hci_cp_remote_oob_data_neg_reply cp;
3347
3348 bacpy(&cp.bdaddr, &ev->bdaddr);
3349 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003350 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003351 }
3352
Szymon Jance1ba1f12011-04-06 13:01:59 +02003353unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003354 hci_dev_unlock(hdev);
3355}
3356
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003357static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3358 struct sk_buff *skb)
3359{
3360 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3361 struct hci_conn *hcon, *bredr_hcon;
3362
3363 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3364 ev->status);
3365
3366 hci_dev_lock(hdev);
3367
3368 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3369 if (!hcon) {
3370 hci_dev_unlock(hdev);
3371 return;
3372 }
3373
3374 if (ev->status) {
3375 hci_conn_del(hcon);
3376 hci_dev_unlock(hdev);
3377 return;
3378 }
3379
3380 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3381
3382 hcon->state = BT_CONNECTED;
3383 bacpy(&hcon->dst, &bredr_hcon->dst);
3384
3385 hci_conn_hold(hcon);
3386 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003387 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003388
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003389 hci_conn_add_sysfs(hcon);
3390
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003391 amp_physical_cfm(bredr_hcon, hcon);
3392
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003393 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003394}
3395
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003396static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3397{
3398 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3399 struct hci_conn *hcon;
3400 struct hci_chan *hchan;
3401 struct amp_mgr *mgr;
3402
3403 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3404 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3405 ev->status);
3406
3407 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3408 if (!hcon)
3409 return;
3410
3411 /* Create AMP hchan */
3412 hchan = hci_chan_create(hcon);
3413 if (!hchan)
3414 return;
3415
3416 hchan->handle = le16_to_cpu(ev->handle);
3417
3418 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3419
3420 mgr = hcon->amp_mgr;
3421 if (mgr && mgr->bredr_chan) {
3422 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3423
3424 l2cap_chan_lock(bredr_chan);
3425
3426 bredr_chan->conn->mtu = hdev->block_mtu;
3427 l2cap_logical_cfm(bredr_chan, hchan, 0);
3428 hci_conn_hold(hcon);
3429
3430 l2cap_chan_unlock(bredr_chan);
3431 }
3432}
3433
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003434static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3435 struct sk_buff *skb)
3436{
3437 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3438 struct hci_chan *hchan;
3439
3440 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3441 le16_to_cpu(ev->handle), ev->status);
3442
3443 if (ev->status)
3444 return;
3445
3446 hci_dev_lock(hdev);
3447
3448 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3449 if (!hchan)
3450 goto unlock;
3451
3452 amp_destroy_logical_link(hchan, ev->reason);
3453
3454unlock:
3455 hci_dev_unlock(hdev);
3456}
3457
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003458static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3459 struct sk_buff *skb)
3460{
3461 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3462 struct hci_conn *hcon;
3463
3464 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3465
3466 if (ev->status)
3467 return;
3468
3469 hci_dev_lock(hdev);
3470
3471 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3472 if (hcon) {
3473 hcon->state = BT_CLOSED;
3474 hci_conn_del(hcon);
3475 }
3476
3477 hci_dev_unlock(hdev);
3478}
3479
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003480static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003481{
3482 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3483 struct hci_conn *conn;
3484
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003485 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003486
3487 hci_dev_lock(hdev);
3488
Andre Guedesb47a09b2012-07-27 15:10:15 -03003489 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003490 if (!conn) {
3491 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3492 if (!conn) {
3493 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003494 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003495 }
Andre Guedes29b79882011-05-31 14:20:54 -03003496
3497 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003498
Marcel Holtmann880be4e2013-10-13 07:25:18 -07003499 /* The advertising parameters for own address type
3500 * define which source address and source address
3501 * type this connections has.
3502 */
3503 if (bacmp(&conn->src, BDADDR_ANY)) {
3504 conn->src_type = ADDR_LE_DEV_PUBLIC;
3505 } else {
3506 bacpy(&conn->src, &hdev->static_addr);
3507 conn->src_type = ADDR_LE_DEV_RANDOM;
3508 }
3509
Andre Guedesb9b343d2012-07-27 15:10:11 -03003510 if (ev->role == LE_CONN_ROLE_MASTER) {
3511 conn->out = true;
3512 conn->link_mode |= HCI_LM_MASTER;
3513 }
Ville Tervob62f3282011-02-10 22:38:50 -03003514 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003515
Andre Guedescd17dec2012-07-27 15:10:16 -03003516 if (ev->status) {
3517 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3518 conn->dst_type, ev->status);
3519 hci_proto_connect_cfm(conn, ev->status);
3520 conn->state = BT_CLOSED;
3521 hci_conn_del(conn);
3522 goto unlock;
3523 }
3524
Johan Hedbergb644ba32012-01-17 21:48:47 +02003525 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3526 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003527 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003528
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003529 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003530 conn->handle = __le16_to_cpu(ev->handle);
3531 conn->state = BT_CONNECTED;
3532
Ville Tervofcd89c02011-02-10 22:38:47 -03003533 hci_conn_add_sysfs(conn);
3534
3535 hci_proto_connect_cfm(conn, ev->status);
3536
3537unlock:
3538 hci_dev_unlock(hdev);
3539}
3540
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003541static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003542{
Andre Guedese95beb42011-09-26 20:48:35 -03003543 u8 num_reports = skb->data[0];
3544 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003545 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003546
Andre Guedese95beb42011-09-26 20:48:35 -03003547 while (num_reports--) {
3548 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003549
Andre Guedes3c9e9192012-01-10 18:20:50 -03003550 rssi = ev->data[ev->length];
3551 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003552 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003553
Andre Guedese95beb42011-09-26 20:48:35 -03003554 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003555 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003556}
3557
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003558static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003559{
3560 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3561 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003562 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003563 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003564 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003565
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003566 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003567
3568 hci_dev_lock(hdev);
3569
3570 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003571 if (conn == NULL)
3572 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003573
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003574 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3575 if (ltk == NULL)
3576 goto not_found;
3577
3578 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003579 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003580
3581 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03003582 conn->pending_sec_level = BT_SECURITY_HIGH;
3583 else
3584 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003585
Andre Guedes89cbb4d2013-07-31 16:25:29 -03003586 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003587
3588 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3589
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003590 if (ltk->type & HCI_SMP_STK) {
3591 list_del(&ltk->list);
3592 kfree(ltk);
3593 }
3594
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003595 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003596
3597 return;
3598
3599not_found:
3600 neg.handle = ev->handle;
3601 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3602 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003603}
3604
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003605static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003606{
3607 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3608
3609 skb_pull(skb, sizeof(*le_ev));
3610
3611 switch (le_ev->subevent) {
3612 case HCI_EV_LE_CONN_COMPLETE:
3613 hci_le_conn_complete_evt(hdev, skb);
3614 break;
3615
Andre Guedes9aa04c92011-05-26 16:23:51 -03003616 case HCI_EV_LE_ADVERTISING_REPORT:
3617 hci_le_adv_report_evt(hdev, skb);
3618 break;
3619
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003620 case HCI_EV_LE_LTK_REQ:
3621 hci_le_ltk_request_evt(hdev, skb);
3622 break;
3623
Ville Tervofcd89c02011-02-10 22:38:47 -03003624 default:
3625 break;
3626 }
3627}
3628
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003629static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3630{
3631 struct hci_ev_channel_selected *ev = (void *) skb->data;
3632 struct hci_conn *hcon;
3633
3634 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3635
3636 skb_pull(skb, sizeof(*ev));
3637
3638 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3639 if (!hcon)
3640 return;
3641
3642 amp_read_loc_assoc_final_data(hdev, hcon);
3643}
3644
Linus Torvalds1da177e2005-04-16 15:20:36 -07003645void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3646{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003647 struct hci_event_hdr *hdr = (void *) skb->data;
3648 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003649
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003650 hci_dev_lock(hdev);
3651
3652 /* Received events are (currently) only needed when a request is
3653 * ongoing so avoid unnecessary memory allocation.
3654 */
3655 if (hdev->req_status == HCI_REQ_PEND) {
3656 kfree_skb(hdev->recv_evt);
3657 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3658 }
3659
3660 hci_dev_unlock(hdev);
3661
Linus Torvalds1da177e2005-04-16 15:20:36 -07003662 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3663
Johan Hedberg02350a72013-04-03 21:50:29 +03003664 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02003665 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
3666 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03003667
3668 hci_req_cmd_complete(hdev, opcode, 0);
3669 }
3670
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003671 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003672 case HCI_EV_INQUIRY_COMPLETE:
3673 hci_inquiry_complete_evt(hdev, skb);
3674 break;
3675
3676 case HCI_EV_INQUIRY_RESULT:
3677 hci_inquiry_result_evt(hdev, skb);
3678 break;
3679
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003680 case HCI_EV_CONN_COMPLETE:
3681 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003682 break;
3683
Linus Torvalds1da177e2005-04-16 15:20:36 -07003684 case HCI_EV_CONN_REQUEST:
3685 hci_conn_request_evt(hdev, skb);
3686 break;
3687
Linus Torvalds1da177e2005-04-16 15:20:36 -07003688 case HCI_EV_DISCONN_COMPLETE:
3689 hci_disconn_complete_evt(hdev, skb);
3690 break;
3691
Linus Torvalds1da177e2005-04-16 15:20:36 -07003692 case HCI_EV_AUTH_COMPLETE:
3693 hci_auth_complete_evt(hdev, skb);
3694 break;
3695
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003696 case HCI_EV_REMOTE_NAME:
3697 hci_remote_name_evt(hdev, skb);
3698 break;
3699
Linus Torvalds1da177e2005-04-16 15:20:36 -07003700 case HCI_EV_ENCRYPT_CHANGE:
3701 hci_encrypt_change_evt(hdev, skb);
3702 break;
3703
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003704 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3705 hci_change_link_key_complete_evt(hdev, skb);
3706 break;
3707
3708 case HCI_EV_REMOTE_FEATURES:
3709 hci_remote_features_evt(hdev, skb);
3710 break;
3711
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003712 case HCI_EV_CMD_COMPLETE:
3713 hci_cmd_complete_evt(hdev, skb);
3714 break;
3715
3716 case HCI_EV_CMD_STATUS:
3717 hci_cmd_status_evt(hdev, skb);
3718 break;
3719
3720 case HCI_EV_ROLE_CHANGE:
3721 hci_role_change_evt(hdev, skb);
3722 break;
3723
3724 case HCI_EV_NUM_COMP_PKTS:
3725 hci_num_comp_pkts_evt(hdev, skb);
3726 break;
3727
3728 case HCI_EV_MODE_CHANGE:
3729 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003730 break;
3731
3732 case HCI_EV_PIN_CODE_REQ:
3733 hci_pin_code_request_evt(hdev, skb);
3734 break;
3735
3736 case HCI_EV_LINK_KEY_REQ:
3737 hci_link_key_request_evt(hdev, skb);
3738 break;
3739
3740 case HCI_EV_LINK_KEY_NOTIFY:
3741 hci_link_key_notify_evt(hdev, skb);
3742 break;
3743
3744 case HCI_EV_CLOCK_OFFSET:
3745 hci_clock_offset_evt(hdev, skb);
3746 break;
3747
Marcel Holtmanna8746412008-07-14 20:13:46 +02003748 case HCI_EV_PKT_TYPE_CHANGE:
3749 hci_pkt_type_change_evt(hdev, skb);
3750 break;
3751
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003752 case HCI_EV_PSCAN_REP_MODE:
3753 hci_pscan_rep_mode_evt(hdev, skb);
3754 break;
3755
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003756 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3757 hci_inquiry_result_with_rssi_evt(hdev, skb);
3758 break;
3759
3760 case HCI_EV_REMOTE_EXT_FEATURES:
3761 hci_remote_ext_features_evt(hdev, skb);
3762 break;
3763
3764 case HCI_EV_SYNC_CONN_COMPLETE:
3765 hci_sync_conn_complete_evt(hdev, skb);
3766 break;
3767
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003768 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3769 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003770 break;
3771
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003772 case HCI_EV_KEY_REFRESH_COMPLETE:
3773 hci_key_refresh_complete_evt(hdev, skb);
3774 break;
3775
Marcel Holtmann04936842008-07-14 20:13:48 +02003776 case HCI_EV_IO_CAPA_REQUEST:
3777 hci_io_capa_request_evt(hdev, skb);
3778 break;
3779
Johan Hedberg03b555e2011-01-04 15:40:05 +02003780 case HCI_EV_IO_CAPA_REPLY:
3781 hci_io_capa_reply_evt(hdev, skb);
3782 break;
3783
Johan Hedberga5c29682011-02-19 12:05:57 -03003784 case HCI_EV_USER_CONFIRM_REQUEST:
3785 hci_user_confirm_request_evt(hdev, skb);
3786 break;
3787
Brian Gix1143d452011-11-23 08:28:34 -08003788 case HCI_EV_USER_PASSKEY_REQUEST:
3789 hci_user_passkey_request_evt(hdev, skb);
3790 break;
3791
Johan Hedberg92a25252012-09-06 18:39:26 +03003792 case HCI_EV_USER_PASSKEY_NOTIFY:
3793 hci_user_passkey_notify_evt(hdev, skb);
3794 break;
3795
3796 case HCI_EV_KEYPRESS_NOTIFY:
3797 hci_keypress_notify_evt(hdev, skb);
3798 break;
3799
Marcel Holtmann04936842008-07-14 20:13:48 +02003800 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3801 hci_simple_pair_complete_evt(hdev, skb);
3802 break;
3803
Marcel Holtmann41a96212008-07-14 20:13:48 +02003804 case HCI_EV_REMOTE_HOST_FEATURES:
3805 hci_remote_host_features_evt(hdev, skb);
3806 break;
3807
Ville Tervofcd89c02011-02-10 22:38:47 -03003808 case HCI_EV_LE_META:
3809 hci_le_meta_evt(hdev, skb);
3810 break;
3811
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003812 case HCI_EV_CHANNEL_SELECTED:
3813 hci_chan_selected_evt(hdev, skb);
3814 break;
3815
Szymon Janc2763eda2011-03-22 13:12:22 +01003816 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3817 hci_remote_oob_data_request_evt(hdev, skb);
3818 break;
3819
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003820 case HCI_EV_PHY_LINK_COMPLETE:
3821 hci_phy_link_complete_evt(hdev, skb);
3822 break;
3823
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003824 case HCI_EV_LOGICAL_LINK_COMPLETE:
3825 hci_loglink_complete_evt(hdev, skb);
3826 break;
3827
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003828 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3829 hci_disconn_loglink_complete_evt(hdev, skb);
3830 break;
3831
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003832 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3833 hci_disconn_phylink_complete_evt(hdev, skb);
3834 break;
3835
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003836 case HCI_EV_NUM_COMP_BLOCKS:
3837 hci_num_comp_blocks_evt(hdev, skb);
3838 break;
3839
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003840 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003841 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003842 break;
3843 }
3844
3845 kfree_skb(skb);
3846 hdev->stat.evt_rx++;
3847}