blob: bbe2d292c4a93fe92f017df91655ae542d287840 [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 Holtmann333140b2008-07-14 20:13:48 +0200421static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
422{
423 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300424 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200425
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300426 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200427
Marcel Holtmann333140b2008-07-14 20:13:48 +0200428 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
429 if (!sent)
430 return;
431
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300432 if (!status) {
433 if (sent->mode)
Johan Hedbergcad718e2013-04-17 15:00:51 +0300434 hdev->features[1][0] |= LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300435 else
Johan Hedbergcad718e2013-04-17 15:00:51 +0300436 hdev->features[1][0] &= ~LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300437 }
438
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200439 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300440 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200441 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300442 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200443 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
444 else
445 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
446 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200447}
448
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200449static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
450{
451 struct hci_rp_read_local_version *rp = (void *) skb->data;
452
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300453 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200454
455 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200456 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200457
458 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200459 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200460 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200461 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200462 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200463
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300464 BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300465 hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200466}
467
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300468static void hci_cc_read_local_commands(struct hci_dev *hdev,
469 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200470{
471 struct hci_rp_read_local_commands *rp = (void *) skb->data;
472
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300473 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200474
Johan Hedberg2177bab2013-03-05 20:37:43 +0200475 if (!rp->status)
476 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200477}
478
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300479static void hci_cc_read_local_features(struct hci_dev *hdev,
480 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200481{
482 struct hci_rp_read_local_features *rp = (void *) skb->data;
483
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300484 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200485
486 if (rp->status)
487 return;
488
489 memcpy(hdev->features, rp->features, 8);
490
491 /* Adjust default settings according to features
492 * supported by device. */
493
Johan Hedbergcad718e2013-04-17 15:00:51 +0300494 if (hdev->features[0][0] & LMP_3SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200495 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
496
Johan Hedbergcad718e2013-04-17 15:00:51 +0300497 if (hdev->features[0][0] & LMP_5SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200498 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
499
Johan Hedbergcad718e2013-04-17 15:00:51 +0300500 if (hdev->features[0][1] & LMP_HV2) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200501 hdev->pkt_type |= (HCI_HV2);
502 hdev->esco_type |= (ESCO_HV2);
503 }
504
Johan Hedbergcad718e2013-04-17 15:00:51 +0300505 if (hdev->features[0][1] & LMP_HV3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200506 hdev->pkt_type |= (HCI_HV3);
507 hdev->esco_type |= (ESCO_HV3);
508 }
509
Andre Guedes45db810f2012-07-24 15:03:49 -0300510 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200511 hdev->esco_type |= (ESCO_EV3);
512
Johan Hedbergcad718e2013-04-17 15:00:51 +0300513 if (hdev->features[0][4] & LMP_EV4)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200514 hdev->esco_type |= (ESCO_EV4);
515
Johan Hedbergcad718e2013-04-17 15:00:51 +0300516 if (hdev->features[0][4] & LMP_EV5)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200517 hdev->esco_type |= (ESCO_EV5);
518
Johan Hedbergcad718e2013-04-17 15:00:51 +0300519 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100520 hdev->esco_type |= (ESCO_2EV3);
521
Johan Hedbergcad718e2013-04-17 15:00:51 +0300522 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100523 hdev->esco_type |= (ESCO_3EV3);
524
Johan Hedbergcad718e2013-04-17 15:00:51 +0300525 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100526 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
527
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200528 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
Johan Hedbergcad718e2013-04-17 15:00:51 +0300529 hdev->features[0][0], hdev->features[0][1],
530 hdev->features[0][2], hdev->features[0][3],
531 hdev->features[0][4], hdev->features[0][5],
532 hdev->features[0][6], hdev->features[0][7]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200533}
534
Andre Guedes971e3a42011-06-30 19:20:52 -0300535static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300536 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300537{
538 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
539
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300540 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300541
542 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200543 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300544
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300545 hdev->max_page = rp->max_page;
546
Johan Hedbergcad718e2013-04-17 15:00:51 +0300547 if (rp->page < HCI_MAX_PAGES)
548 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300549}
550
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200551static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300552 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200553{
554 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
555
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300556 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200557
Johan Hedberg42c6b122013-03-05 20:37:49 +0200558 if (!rp->status)
559 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200560}
561
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200562static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
563{
564 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
565
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300566 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200567
568 if (rp->status)
569 return;
570
571 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
572 hdev->sco_mtu = rp->sco_mtu;
573 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
574 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
575
576 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
577 hdev->sco_mtu = 64;
578 hdev->sco_pkts = 8;
579 }
580
581 hdev->acl_cnt = hdev->acl_pkts;
582 hdev->sco_cnt = hdev->sco_pkts;
583
Gustavo Padovan807deac2012-05-17 00:36:24 -0300584 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
585 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200586}
587
588static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
589{
590 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
591
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300592 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200593
594 if (!rp->status)
595 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200596}
597
Johan Hedbergf332ec62013-03-15 17:07:11 -0500598static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
599 struct sk_buff *skb)
600{
601 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
602
603 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
604
605 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
606 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
607 hdev->page_scan_window = __le16_to_cpu(rp->window);
608 }
609}
610
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500611static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
612 struct sk_buff *skb)
613{
614 u8 status = *((u8 *) skb->data);
615 struct hci_cp_write_page_scan_activity *sent;
616
617 BT_DBG("%s status 0x%2.2x", hdev->name, status);
618
619 if (status)
620 return;
621
622 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
623 if (!sent)
624 return;
625
626 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
627 hdev->page_scan_window = __le16_to_cpu(sent->window);
628}
629
Johan Hedbergf332ec62013-03-15 17:07:11 -0500630static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
631 struct sk_buff *skb)
632{
633 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
634
635 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
636
637 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
638 hdev->page_scan_type = rp->type;
639}
640
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500641static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
642 struct sk_buff *skb)
643{
644 u8 status = *((u8 *) skb->data);
645 u8 *type;
646
647 BT_DBG("%s status 0x%2.2x", hdev->name, status);
648
649 if (status)
650 return;
651
652 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
653 if (type)
654 hdev->page_scan_type = *type;
655}
656
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200657static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300658 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200659{
660 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
661
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300662 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200663
664 if (rp->status)
665 return;
666
667 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
668 hdev->block_len = __le16_to_cpu(rp->block_len);
669 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
670
671 hdev->block_cnt = hdev->num_blocks;
672
673 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300674 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200675}
676
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300677static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300678 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300679{
680 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
681
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300682 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300683
684 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300685 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300686
687 hdev->amp_status = rp->amp_status;
688 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
689 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
690 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
691 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
692 hdev->amp_type = rp->amp_type;
693 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
694 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
695 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
696 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
697
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300698a2mp_rsp:
699 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300700}
701
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300702static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
703 struct sk_buff *skb)
704{
705 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
706 struct amp_assoc *assoc = &hdev->loc_assoc;
707 size_t rem_len, frag_len;
708
709 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
710
711 if (rp->status)
712 goto a2mp_rsp;
713
714 frag_len = skb->len - sizeof(*rp);
715 rem_len = __le16_to_cpu(rp->rem_len);
716
717 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300718 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300719
720 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
721 assoc->offset += frag_len;
722
723 /* Read other fragments */
724 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
725
726 return;
727 }
728
729 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
730 assoc->len = assoc->offset + rem_len;
731 assoc->offset = 0;
732
733a2mp_rsp:
734 /* Send A2MP Rsp when all fragments are received */
735 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300736 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300737}
738
Johan Hedbergd5859e22011-01-25 01:19:58 +0200739static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300740 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200741{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700742 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200743
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300744 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200745
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700746 if (!rp->status)
747 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200748}
749
Johan Hedberg980e1a52011-01-22 06:10:07 +0200750static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
751{
752 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
753 struct hci_cp_pin_code_reply *cp;
754 struct hci_conn *conn;
755
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300756 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200757
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200758 hci_dev_lock(hdev);
759
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200760 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200761 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200762
Mikel Astizfa1bd912012-08-09 09:52:29 +0200763 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200764 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200765
766 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
767 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200768 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200769
770 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
771 if (conn)
772 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200773
774unlock:
775 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200776}
777
778static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
779{
780 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
781
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300782 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200783
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200784 hci_dev_lock(hdev);
785
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200786 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200787 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300788 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200789
790 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200791}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200792
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300793static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
794 struct sk_buff *skb)
795{
796 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
797
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300798 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300799
800 if (rp->status)
801 return;
802
803 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
804 hdev->le_pkts = rp->le_max_pkt;
805
806 hdev->le_cnt = hdev->le_pkts;
807
808 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300809}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200810
Johan Hedberg60e77322013-01-22 14:01:59 +0200811static void hci_cc_le_read_local_features(struct hci_dev *hdev,
812 struct sk_buff *skb)
813{
814 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
815
816 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
817
818 if (!rp->status)
819 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200820}
821
Johan Hedberg8fa19092012-10-19 20:57:49 +0300822static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
823 struct sk_buff *skb)
824{
825 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
826
827 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
828
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500829 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300830 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300831}
832
Johan Hedberga5c29682011-02-19 12:05:57 -0300833static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
834{
835 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
836
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300837 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300838
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200839 hci_dev_lock(hdev);
840
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200841 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300842 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
843 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200844
845 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300846}
847
848static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300849 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300850{
851 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
852
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300853 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300854
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200855 hci_dev_lock(hdev);
856
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200857 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200858 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300859 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200860
861 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300862}
863
Brian Gix1143d452011-11-23 08:28:34 -0800864static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
865{
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);
Brian Gix1143d452011-11-23 08:28:34 -0800869
870 hci_dev_lock(hdev);
871
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200872 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200873 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300874 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800875
876 hci_dev_unlock(hdev);
877}
878
879static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300880 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800881{
882 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
883
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300884 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800885
886 hci_dev_lock(hdev);
887
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200888 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800889 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300890 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800891
892 hci_dev_unlock(hdev);
893}
894
Szymon Jancc35938b2011-03-22 13:12:21 +0100895static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300896 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100897{
898 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
899
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300900 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100901
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200902 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +0200903 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +0100904 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200905 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100906}
907
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100908static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
909{
910 __u8 *sent, status = *((__u8 *) skb->data);
911
912 BT_DBG("%s status 0x%2.2x", hdev->name, status);
913
914 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
915 if (!sent)
916 return;
917
918 hci_dev_lock(hdev);
919
920 if (!status) {
921 if (*sent)
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200922 set_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100923 else
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200924 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100925 }
926
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500927 if (!test_bit(HCI_INIT, &hdev->flags)) {
928 struct hci_request req;
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100929
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500930 hci_req_init(&req, hdev);
931 hci_update_ad(&req);
932 hci_req_run(&req, NULL);
933 }
934
935 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100936}
937
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300938static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300939 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300940{
941 struct hci_cp_le_set_scan_enable *cp;
942 __u8 status = *((__u8 *) skb->data);
943
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300944 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300945
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300946 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
947 if (!cp)
948 return;
949
Andre Guedes3fd319b2013-04-30 15:29:36 -0300950 if (status)
951 return;
952
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200953 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -0300954 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300955 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200956 break;
957
Andre Guedes76a388b2013-04-04 20:21:02 -0300958 case LE_SCAN_DISABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300959 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200960 break;
961
962 default:
963 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
964 break;
Andre Guedes35815082011-05-26 16:23:53 -0300965 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300966}
967
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200968static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
969 struct sk_buff *skb)
970{
971 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
972
973 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
974
975 if (!rp->status)
976 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200977}
978
Johan Hedberg9b008c02013-01-22 14:02:01 +0200979static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
980 struct sk_buff *skb)
981{
982 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
983
984 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
985
986 if (!rp->status)
987 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +0200988}
989
Gustavo Padovan6039aa72012-05-23 04:04:18 -0300990static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
991 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -0300992{
Johan Hedberg06199cf2012-02-22 16:37:11 +0200993 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -0300994 __u8 status = *((__u8 *) skb->data);
995
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300996 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -0300997
Johan Hedberg06199cf2012-02-22 16:37:11 +0200998 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +0200999 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001000 return;
1001
Johan Hedberg8f984df2012-02-28 01:07:22 +02001002 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001003 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001004 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001005 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1006 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001007 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001008 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001009 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001010 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001011
1012 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001013 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001014 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001015 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001016 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001017}
1018
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001019static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1020 struct sk_buff *skb)
1021{
1022 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1023
1024 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1025 hdev->name, rp->status, rp->phy_handle);
1026
1027 if (rp->status)
1028 return;
1029
1030 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1031}
1032
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001033static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001034{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001035 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001036
1037 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001038 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001039 return;
1040 }
1041
Andre Guedes89352e72011-11-04 14:16:53 -03001042 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001043}
1044
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001045static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001047 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049
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 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 if (!cp)
1054 return;
1055
1056 hci_dev_lock(hdev);
1057
1058 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1059
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001060 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061
1062 if (status) {
1063 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001064 if (status != 0x0c || conn->attempt > 2) {
1065 conn->state = BT_CLOSED;
1066 hci_proto_connect_cfm(conn, status);
1067 hci_conn_del(conn);
1068 } else
1069 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 }
1071 } else {
1072 if (!conn) {
1073 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1074 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001075 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076 conn->link_mode |= HCI_LM_MASTER;
1077 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001078 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079 }
1080 }
1081
1082 hci_dev_unlock(hdev);
1083}
1084
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001085static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001087 struct hci_cp_add_sco *cp;
1088 struct hci_conn *acl, *sco;
1089 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001091 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001092
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001093 if (!status)
1094 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001096 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1097 if (!cp)
1098 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001100 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001102 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001103
1104 hci_dev_lock(hdev);
1105
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001106 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001107 if (acl) {
1108 sco = acl->link;
1109 if (sco) {
1110 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001111
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001112 hci_proto_connect_cfm(sco, status);
1113 hci_conn_del(sco);
1114 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001115 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001116
1117 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118}
1119
Marcel Holtmannf8558552008-07-14 20:13:49 +02001120static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1121{
1122 struct hci_cp_auth_requested *cp;
1123 struct hci_conn *conn;
1124
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001125 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001126
1127 if (!status)
1128 return;
1129
1130 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1131 if (!cp)
1132 return;
1133
1134 hci_dev_lock(hdev);
1135
1136 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1137 if (conn) {
1138 if (conn->state == BT_CONFIG) {
1139 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001140 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001141 }
1142 }
1143
1144 hci_dev_unlock(hdev);
1145}
1146
1147static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1148{
1149 struct hci_cp_set_conn_encrypt *cp;
1150 struct hci_conn *conn;
1151
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001152 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001153
1154 if (!status)
1155 return;
1156
1157 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1158 if (!cp)
1159 return;
1160
1161 hci_dev_lock(hdev);
1162
1163 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1164 if (conn) {
1165 if (conn->state == BT_CONFIG) {
1166 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001167 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001168 }
1169 }
1170
1171 hci_dev_unlock(hdev);
1172}
1173
Johan Hedberg127178d2010-11-18 22:22:29 +02001174static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001175 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001176{
Johan Hedberg392599b2010-11-18 22:22:28 +02001177 if (conn->state != BT_CONFIG || !conn->out)
1178 return 0;
1179
Johan Hedberg765c2a92011-01-19 12:06:52 +05301180 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001181 return 0;
1182
1183 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001184 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001185 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1186 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001187 return 0;
1188
Johan Hedberg392599b2010-11-18 22:22:28 +02001189 return 1;
1190}
1191
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001192static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001193 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001194{
1195 struct hci_cp_remote_name_req cp;
1196
1197 memset(&cp, 0, sizeof(cp));
1198
1199 bacpy(&cp.bdaddr, &e->data.bdaddr);
1200 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1201 cp.pscan_mode = e->data.pscan_mode;
1202 cp.clock_offset = e->data.clock_offset;
1203
1204 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1205}
1206
Johan Hedbergb644ba32012-01-17 21:48:47 +02001207static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001208{
1209 struct discovery_state *discov = &hdev->discovery;
1210 struct inquiry_entry *e;
1211
Johan Hedbergb644ba32012-01-17 21:48:47 +02001212 if (list_empty(&discov->resolve))
1213 return false;
1214
1215 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001216 if (!e)
1217 return false;
1218
Johan Hedbergb644ba32012-01-17 21:48:47 +02001219 if (hci_resolve_name(hdev, e) == 0) {
1220 e->name_state = NAME_PENDING;
1221 return true;
1222 }
1223
1224 return false;
1225}
1226
1227static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001228 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001229{
1230 struct discovery_state *discov = &hdev->discovery;
1231 struct inquiry_entry *e;
1232
1233 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001234 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1235 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001236
1237 if (discov->state == DISCOVERY_STOPPED)
1238 return;
1239
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001240 if (discov->state == DISCOVERY_STOPPING)
1241 goto discov_complete;
1242
1243 if (discov->state != DISCOVERY_RESOLVING)
1244 return;
1245
1246 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001247 /* If the device was not found in a list of found devices names of which
1248 * are pending. there is no need to continue resolving a next name as it
1249 * will be done upon receiving another Remote Name Request Complete
1250 * Event */
1251 if (!e)
1252 return;
1253
1254 list_del(&e->list);
1255 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001256 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001257 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1258 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001259 } else {
1260 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001261 }
1262
Johan Hedbergb644ba32012-01-17 21:48:47 +02001263 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001264 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001265
1266discov_complete:
1267 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1268}
1269
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001270static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1271{
Johan Hedberg127178d2010-11-18 22:22:29 +02001272 struct hci_cp_remote_name_req *cp;
1273 struct hci_conn *conn;
1274
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001275 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001276
1277 /* If successful wait for the name req complete event before
1278 * checking for the need to do authentication */
1279 if (!status)
1280 return;
1281
1282 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1283 if (!cp)
1284 return;
1285
1286 hci_dev_lock(hdev);
1287
1288 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001289
1290 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1291 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1292
Johan Hedberg79c6c702011-04-28 11:28:55 -07001293 if (!conn)
1294 goto unlock;
1295
1296 if (!hci_outgoing_auth_needed(hdev, conn))
1297 goto unlock;
1298
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001299 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001300 struct hci_cp_auth_requested auth_cp;
1301
1302 auth_cp.handle = __cpu_to_le16(conn->handle);
1303 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1304 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001305 }
1306
Johan Hedberg79c6c702011-04-28 11:28:55 -07001307unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001308 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001309}
1310
Marcel Holtmann769be972008-07-14 20:13:49 +02001311static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1312{
1313 struct hci_cp_read_remote_features *cp;
1314 struct hci_conn *conn;
1315
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001316 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001317
1318 if (!status)
1319 return;
1320
1321 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1322 if (!cp)
1323 return;
1324
1325 hci_dev_lock(hdev);
1326
1327 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1328 if (conn) {
1329 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001330 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001331 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001332 }
1333 }
1334
1335 hci_dev_unlock(hdev);
1336}
1337
1338static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1339{
1340 struct hci_cp_read_remote_ext_features *cp;
1341 struct hci_conn *conn;
1342
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001343 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001344
1345 if (!status)
1346 return;
1347
1348 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1349 if (!cp)
1350 return;
1351
1352 hci_dev_lock(hdev);
1353
1354 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1355 if (conn) {
1356 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001357 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001358 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001359 }
1360 }
1361
1362 hci_dev_unlock(hdev);
1363}
1364
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001365static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1366{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001367 struct hci_cp_setup_sync_conn *cp;
1368 struct hci_conn *acl, *sco;
1369 __u16 handle;
1370
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001371 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001372
1373 if (!status)
1374 return;
1375
1376 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1377 if (!cp)
1378 return;
1379
1380 handle = __le16_to_cpu(cp->handle);
1381
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001382 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001383
1384 hci_dev_lock(hdev);
1385
1386 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001387 if (acl) {
1388 sco = acl->link;
1389 if (sco) {
1390 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001391
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001392 hci_proto_connect_cfm(sco, status);
1393 hci_conn_del(sco);
1394 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001395 }
1396
1397 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001398}
1399
1400static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1401{
1402 struct hci_cp_sniff_mode *cp;
1403 struct hci_conn *conn;
1404
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001405 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001406
1407 if (!status)
1408 return;
1409
1410 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1411 if (!cp)
1412 return;
1413
1414 hci_dev_lock(hdev);
1415
1416 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001417 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001418 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001419
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001420 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001421 hci_sco_setup(conn, status);
1422 }
1423
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001424 hci_dev_unlock(hdev);
1425}
1426
1427static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1428{
1429 struct hci_cp_exit_sniff_mode *cp;
1430 struct hci_conn *conn;
1431
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001432 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001433
1434 if (!status)
1435 return;
1436
1437 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1438 if (!cp)
1439 return;
1440
1441 hci_dev_lock(hdev);
1442
1443 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001444 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001445 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001446
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001447 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001448 hci_sco_setup(conn, status);
1449 }
1450
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001451 hci_dev_unlock(hdev);
1452}
1453
Johan Hedberg88c3df12012-02-09 14:27:38 +02001454static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1455{
1456 struct hci_cp_disconnect *cp;
1457 struct hci_conn *conn;
1458
1459 if (!status)
1460 return;
1461
1462 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1463 if (!cp)
1464 return;
1465
1466 hci_dev_lock(hdev);
1467
1468 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1469 if (conn)
1470 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001471 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001472
1473 hci_dev_unlock(hdev);
1474}
1475
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001476static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1477{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001478 struct hci_cp_create_phy_link *cp;
1479
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001480 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001481
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001482 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1483 if (!cp)
1484 return;
1485
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001486 hci_dev_lock(hdev);
1487
1488 if (status) {
1489 struct hci_conn *hcon;
1490
1491 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1492 if (hcon)
1493 hci_conn_del(hcon);
1494 } else {
1495 amp_write_remote_assoc(hdev, cp->phy_handle);
1496 }
1497
1498 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001499}
1500
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001501static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1502{
1503 struct hci_cp_accept_phy_link *cp;
1504
1505 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1506
1507 if (status)
1508 return;
1509
1510 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1511 if (!cp)
1512 return;
1513
1514 amp_write_remote_assoc(hdev, cp->phy_handle);
1515}
1516
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001517static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001518{
1519 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001520 struct discovery_state *discov = &hdev->discovery;
1521 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001522
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001523 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001524
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001525 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001526
1527 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1528 return;
1529
Andre Guedes3e13fa12013-03-27 20:04:56 -03001530 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1531 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1532
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001533 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001534 return;
1535
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001536 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001537
Andre Guedes343f9352012-02-17 20:39:37 -03001538 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001539 goto unlock;
1540
1541 if (list_empty(&discov->resolve)) {
1542 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1543 goto unlock;
1544 }
1545
1546 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1547 if (e && hci_resolve_name(hdev, e) == 0) {
1548 e->name_state = NAME_PENDING;
1549 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1550 } else {
1551 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1552 }
1553
1554unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001555 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001556}
1557
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001558static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001560 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001561 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562 int num_rsp = *((__u8 *) skb->data);
1563
1564 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1565
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001566 if (!num_rsp)
1567 return;
1568
Andre Guedes1519cc12012-03-21 00:03:38 -03001569 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1570 return;
1571
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001573
Johan Hedberge17acd42011-03-30 23:57:16 +03001574 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001575 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001576
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 bacpy(&data.bdaddr, &info->bdaddr);
1578 data.pscan_rep_mode = info->pscan_rep_mode;
1579 data.pscan_period_mode = info->pscan_period_mode;
1580 data.pscan_mode = info->pscan_mode;
1581 memcpy(data.dev_class, info->dev_class, 3);
1582 data.clock_offset = info->clock_offset;
1583 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001584 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001585
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001586 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001587 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001588 info->dev_class, 0, !name_known, ssp, NULL,
1589 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001591
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592 hci_dev_unlock(hdev);
1593}
1594
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001595static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001597 struct hci_ev_conn_complete *ev = (void *) skb->data;
1598 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001600 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001601
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001603
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001604 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001605 if (!conn) {
1606 if (ev->link_type != SCO_LINK)
1607 goto unlock;
1608
1609 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1610 if (!conn)
1611 goto unlock;
1612
1613 conn->type = SCO_LINK;
1614 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001615
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001616 if (!ev->status) {
1617 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001618
1619 if (conn->type == ACL_LINK) {
1620 conn->state = BT_CONFIG;
1621 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001622
1623 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1624 !hci_find_link_key(hdev, &ev->bdaddr))
1625 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1626 else
1627 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001628 } else
1629 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001630
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001631 hci_conn_add_sysfs(conn);
1632
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001633 if (test_bit(HCI_AUTH, &hdev->flags))
1634 conn->link_mode |= HCI_LM_AUTH;
1635
1636 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1637 conn->link_mode |= HCI_LM_ENCRYPT;
1638
1639 /* Get remote features */
1640 if (conn->type == ACL_LINK) {
1641 struct hci_cp_read_remote_features cp;
1642 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001643 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001644 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001645 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001646
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001647 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001648 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001649 struct hci_cp_change_conn_ptype cp;
1650 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001651 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001652 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1653 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001654 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001655 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001656 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001657 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001658 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001659 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001660 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001661
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001662 if (conn->type == ACL_LINK)
1663 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001664
Marcel Holtmann769be972008-07-14 20:13:49 +02001665 if (ev->status) {
1666 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001667 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001668 } else if (ev->link_type != ACL_LINK)
1669 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001670
1671unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001673
1674 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675}
1676
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001677static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001679 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680 int mask = hdev->link_mode;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001681 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001683 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001684 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001686 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1687 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688
Szymon Janc138d22e2011-02-17 16:44:23 +01001689 if ((mask & HCI_LM_ACCEPT) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001690 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001692 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694
1695 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001696
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001697 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1698 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001699 memcpy(ie->data.dev_class, ev->dev_class, 3);
1700
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001701 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1702 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001704 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1705 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001706 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 hci_dev_unlock(hdev);
1708 return;
1709 }
1710 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001711
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001713
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 hci_dev_unlock(hdev);
1715
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001716 if (ev->link_type == ACL_LINK ||
1717 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001718 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001719 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001721 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001723 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1724 cp.role = 0x00; /* Become master */
1725 else
1726 cp.role = 0x01; /* Remain slave */
1727
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001728 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1729 &cp);
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001730 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001731 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001732 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001733
1734 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001735 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001736
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001737 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1738 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1739 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001740 cp.content_format = cpu_to_le16(hdev->voice_setting);
1741 cp.retrans_effort = 0xff;
1742
1743 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001744 sizeof(cp), &cp);
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001745 } else {
1746 conn->state = BT_CONNECT2;
1747 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001748 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 } else {
1750 /* Connection rejected */
1751 struct hci_cp_reject_conn_req cp;
1752
1753 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001754 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001755 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 }
1757}
1758
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001759static u8 hci_to_mgmt_reason(u8 err)
1760{
1761 switch (err) {
1762 case HCI_ERROR_CONNECTION_TIMEOUT:
1763 return MGMT_DEV_DISCONN_TIMEOUT;
1764 case HCI_ERROR_REMOTE_USER_TERM:
1765 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1766 case HCI_ERROR_REMOTE_POWER_OFF:
1767 return MGMT_DEV_DISCONN_REMOTE;
1768 case HCI_ERROR_LOCAL_HOST_TERM:
1769 return MGMT_DEV_DISCONN_LOCAL_HOST;
1770 default:
1771 return MGMT_DEV_DISCONN_UNKNOWN;
1772 }
1773}
1774
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001775static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001777 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001778 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001780 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782 hci_dev_lock(hdev);
1783
Marcel Holtmann04837f62006-07-03 10:02:33 +02001784 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001785 if (!conn)
1786 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001787
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001788 if (ev->status == 0)
1789 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790
Johan Hedbergb644ba32012-01-17 21:48:47 +02001791 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001792 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001793 if (ev->status) {
Johan Hedberg88c3df12012-02-09 14:27:38 +02001794 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001795 conn->dst_type, ev->status);
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001796 } else {
1797 u8 reason = hci_to_mgmt_reason(ev->reason);
1798
Johan Hedbergafc747a2012-01-15 18:11:07 +02001799 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001800 conn->dst_type, reason);
1801 }
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001802 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001803
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001804 if (ev->status == 0) {
Johan Hedberg22102462013-10-05 12:01:06 +02001805 u8 type = conn->type;
1806
1807 if (type == ACL_LINK && conn->flush_key)
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301808 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001809 hci_proto_disconn_cfm(conn, ev->reason);
1810 hci_conn_del(conn);
Johan Hedberg22102462013-10-05 12:01:06 +02001811
1812 /* Re-enable advertising if necessary, since it might
1813 * have been disabled by the connection. From the
1814 * HCI_LE_Set_Advertise_Enable command description in
1815 * the core specification (v4.0):
1816 * "The Controller shall continue advertising until the Host
1817 * issues an LE_Set_Advertise_Enable command with
1818 * Advertising_Enable set to 0x00 (Advertising is disabled)
1819 * or until a connection is created or until the Advertising
1820 * is timed out due to Directed Advertising."
1821 */
1822 if (type == LE_LINK)
Marcel Holtmann5976e602013-10-06 04:08:14 -07001823 mgmt_reenable_advertising(hdev);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001824 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001825
1826unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827 hci_dev_unlock(hdev);
1828}
1829
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001830static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001831{
1832 struct hci_ev_auth_complete *ev = (void *) skb->data;
1833 struct hci_conn *conn;
1834
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001835 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001836
1837 hci_dev_lock(hdev);
1838
1839 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001840 if (!conn)
1841 goto unlock;
1842
1843 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001844 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001845 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001846 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001847 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001848 conn->link_mode |= HCI_LM_AUTH;
1849 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001850 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001851 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001852 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001853 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001854 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001855
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001856 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1857 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001858
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001859 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001860 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001861 struct hci_cp_set_conn_encrypt cp;
1862 cp.handle = ev->handle;
1863 cp.encrypt = 0x01;
1864 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001865 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001866 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001867 conn->state = BT_CONNECTED;
1868 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001869 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001870 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001871 } else {
1872 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001873
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001874 hci_conn_hold(conn);
1875 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001876 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001877 }
1878
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001879 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001880 if (!ev->status) {
1881 struct hci_cp_set_conn_encrypt cp;
1882 cp.handle = ev->handle;
1883 cp.encrypt = 0x01;
1884 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001885 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001886 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001887 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001888 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001889 }
1890 }
1891
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001892unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001893 hci_dev_unlock(hdev);
1894}
1895
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001896static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001897{
Johan Hedberg127178d2010-11-18 22:22:29 +02001898 struct hci_ev_remote_name *ev = (void *) skb->data;
1899 struct hci_conn *conn;
1900
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001901 BT_DBG("%s", hdev->name);
1902
1903 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001904
1905 hci_dev_lock(hdev);
1906
1907 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001908
1909 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1910 goto check_auth;
1911
1912 if (ev->status == 0)
1913 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001914 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001915 else
1916 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1917
1918check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001919 if (!conn)
1920 goto unlock;
1921
1922 if (!hci_outgoing_auth_needed(hdev, conn))
1923 goto unlock;
1924
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001925 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001926 struct hci_cp_auth_requested cp;
1927 cp.handle = __cpu_to_le16(conn->handle);
1928 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1929 }
1930
Johan Hedberg79c6c702011-04-28 11:28:55 -07001931unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001932 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001933}
1934
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001935static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001936{
1937 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1938 struct hci_conn *conn;
1939
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001940 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001941
1942 hci_dev_lock(hdev);
1943
1944 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1945 if (conn) {
1946 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001947 if (ev->encrypt) {
1948 /* Encryption implies authentication */
1949 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001950 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001951 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001952 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001953 conn->link_mode &= ~HCI_LM_ENCRYPT;
1954 }
1955
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001956 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001957
Gustavo Padovana7d77232012-05-13 03:20:07 -03001958 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03001959 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02001960 hci_conn_drop(conn);
Gustavo Padovana7d77232012-05-13 03:20:07 -03001961 goto unlock;
1962 }
1963
Marcel Holtmannf8558552008-07-14 20:13:49 +02001964 if (conn->state == BT_CONFIG) {
1965 if (!ev->status)
1966 conn->state = BT_CONNECTED;
1967
1968 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001969 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001970 } else
1971 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001972 }
1973
Gustavo Padovana7d77232012-05-13 03:20:07 -03001974unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001975 hci_dev_unlock(hdev);
1976}
1977
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001978static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
1979 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001980{
1981 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1982 struct hci_conn *conn;
1983
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001984 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001985
1986 hci_dev_lock(hdev);
1987
1988 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1989 if (conn) {
1990 if (!ev->status)
1991 conn->link_mode |= HCI_LM_SECURE;
1992
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001993 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001994
1995 hci_key_change_cfm(conn, ev->status);
1996 }
1997
1998 hci_dev_unlock(hdev);
1999}
2000
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002001static void hci_remote_features_evt(struct hci_dev *hdev,
2002 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002003{
2004 struct hci_ev_remote_features *ev = (void *) skb->data;
2005 struct hci_conn *conn;
2006
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002007 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002008
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002009 hci_dev_lock(hdev);
2010
2011 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002012 if (!conn)
2013 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002014
Johan Hedbergccd556f2010-11-10 17:11:51 +02002015 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002016 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002017
2018 if (conn->state != BT_CONFIG)
2019 goto unlock;
2020
2021 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2022 struct hci_cp_read_remote_ext_features cp;
2023 cp.handle = ev->handle;
2024 cp.page = 0x01;
2025 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002026 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002027 goto unlock;
2028 }
2029
Johan Hedberg671267b2012-05-12 16:11:50 -03002030 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002031 struct hci_cp_remote_name_req cp;
2032 memset(&cp, 0, sizeof(cp));
2033 bacpy(&cp.bdaddr, &conn->dst);
2034 cp.pscan_rep_mode = 0x02;
2035 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002036 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2037 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002038 conn->dst_type, 0, NULL, 0,
2039 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002040
Johan Hedberg127178d2010-11-18 22:22:29 +02002041 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002042 conn->state = BT_CONNECTED;
2043 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002044 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002045 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002046
Johan Hedbergccd556f2010-11-10 17:11:51 +02002047unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002048 hci_dev_unlock(hdev);
2049}
2050
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002051static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002052{
2053 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002054 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002055 __u16 opcode;
2056
2057 skb_pull(skb, sizeof(*ev));
2058
2059 opcode = __le16_to_cpu(ev->opcode);
2060
2061 switch (opcode) {
2062 case HCI_OP_INQUIRY_CANCEL:
2063 hci_cc_inquiry_cancel(hdev, skb);
2064 break;
2065
Andre Guedes4d934832012-03-21 00:03:35 -03002066 case HCI_OP_PERIODIC_INQ:
2067 hci_cc_periodic_inq(hdev, skb);
2068 break;
2069
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002070 case HCI_OP_EXIT_PERIODIC_INQ:
2071 hci_cc_exit_periodic_inq(hdev, skb);
2072 break;
2073
2074 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2075 hci_cc_remote_name_req_cancel(hdev, skb);
2076 break;
2077
2078 case HCI_OP_ROLE_DISCOVERY:
2079 hci_cc_role_discovery(hdev, skb);
2080 break;
2081
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002082 case HCI_OP_READ_LINK_POLICY:
2083 hci_cc_read_link_policy(hdev, skb);
2084 break;
2085
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002086 case HCI_OP_WRITE_LINK_POLICY:
2087 hci_cc_write_link_policy(hdev, skb);
2088 break;
2089
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002090 case HCI_OP_READ_DEF_LINK_POLICY:
2091 hci_cc_read_def_link_policy(hdev, skb);
2092 break;
2093
2094 case HCI_OP_WRITE_DEF_LINK_POLICY:
2095 hci_cc_write_def_link_policy(hdev, skb);
2096 break;
2097
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002098 case HCI_OP_RESET:
2099 hci_cc_reset(hdev, skb);
2100 break;
2101
2102 case HCI_OP_WRITE_LOCAL_NAME:
2103 hci_cc_write_local_name(hdev, skb);
2104 break;
2105
2106 case HCI_OP_READ_LOCAL_NAME:
2107 hci_cc_read_local_name(hdev, skb);
2108 break;
2109
2110 case HCI_OP_WRITE_AUTH_ENABLE:
2111 hci_cc_write_auth_enable(hdev, skb);
2112 break;
2113
2114 case HCI_OP_WRITE_ENCRYPT_MODE:
2115 hci_cc_write_encrypt_mode(hdev, skb);
2116 break;
2117
2118 case HCI_OP_WRITE_SCAN_ENABLE:
2119 hci_cc_write_scan_enable(hdev, skb);
2120 break;
2121
2122 case HCI_OP_READ_CLASS_OF_DEV:
2123 hci_cc_read_class_of_dev(hdev, skb);
2124 break;
2125
2126 case HCI_OP_WRITE_CLASS_OF_DEV:
2127 hci_cc_write_class_of_dev(hdev, skb);
2128 break;
2129
2130 case HCI_OP_READ_VOICE_SETTING:
2131 hci_cc_read_voice_setting(hdev, skb);
2132 break;
2133
2134 case HCI_OP_WRITE_VOICE_SETTING:
2135 hci_cc_write_voice_setting(hdev, skb);
2136 break;
2137
Marcel Holtmann333140b2008-07-14 20:13:48 +02002138 case HCI_OP_WRITE_SSP_MODE:
2139 hci_cc_write_ssp_mode(hdev, skb);
2140 break;
2141
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002142 case HCI_OP_READ_LOCAL_VERSION:
2143 hci_cc_read_local_version(hdev, skb);
2144 break;
2145
2146 case HCI_OP_READ_LOCAL_COMMANDS:
2147 hci_cc_read_local_commands(hdev, skb);
2148 break;
2149
2150 case HCI_OP_READ_LOCAL_FEATURES:
2151 hci_cc_read_local_features(hdev, skb);
2152 break;
2153
Andre Guedes971e3a42011-06-30 19:20:52 -03002154 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2155 hci_cc_read_local_ext_features(hdev, skb);
2156 break;
2157
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002158 case HCI_OP_READ_BUFFER_SIZE:
2159 hci_cc_read_buffer_size(hdev, skb);
2160 break;
2161
2162 case HCI_OP_READ_BD_ADDR:
2163 hci_cc_read_bd_addr(hdev, skb);
2164 break;
2165
Johan Hedbergf332ec62013-03-15 17:07:11 -05002166 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2167 hci_cc_read_page_scan_activity(hdev, skb);
2168 break;
2169
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002170 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2171 hci_cc_write_page_scan_activity(hdev, skb);
2172 break;
2173
Johan Hedbergf332ec62013-03-15 17:07:11 -05002174 case HCI_OP_READ_PAGE_SCAN_TYPE:
2175 hci_cc_read_page_scan_type(hdev, skb);
2176 break;
2177
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002178 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2179 hci_cc_write_page_scan_type(hdev, skb);
2180 break;
2181
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002182 case HCI_OP_READ_DATA_BLOCK_SIZE:
2183 hci_cc_read_data_block_size(hdev, skb);
2184 break;
2185
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002186 case HCI_OP_READ_FLOW_CONTROL_MODE:
2187 hci_cc_read_flow_control_mode(hdev, skb);
2188 break;
2189
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002190 case HCI_OP_READ_LOCAL_AMP_INFO:
2191 hci_cc_read_local_amp_info(hdev, skb);
2192 break;
2193
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002194 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2195 hci_cc_read_local_amp_assoc(hdev, skb);
2196 break;
2197
Johan Hedbergd5859e22011-01-25 01:19:58 +02002198 case HCI_OP_READ_INQ_RSP_TX_POWER:
2199 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2200 break;
2201
Johan Hedberg980e1a52011-01-22 06:10:07 +02002202 case HCI_OP_PIN_CODE_REPLY:
2203 hci_cc_pin_code_reply(hdev, skb);
2204 break;
2205
2206 case HCI_OP_PIN_CODE_NEG_REPLY:
2207 hci_cc_pin_code_neg_reply(hdev, skb);
2208 break;
2209
Szymon Jancc35938b2011-03-22 13:12:21 +01002210 case HCI_OP_READ_LOCAL_OOB_DATA:
2211 hci_cc_read_local_oob_data_reply(hdev, skb);
2212 break;
2213
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002214 case HCI_OP_LE_READ_BUFFER_SIZE:
2215 hci_cc_le_read_buffer_size(hdev, skb);
2216 break;
2217
Johan Hedberg60e77322013-01-22 14:01:59 +02002218 case HCI_OP_LE_READ_LOCAL_FEATURES:
2219 hci_cc_le_read_local_features(hdev, skb);
2220 break;
2221
Johan Hedberg8fa19092012-10-19 20:57:49 +03002222 case HCI_OP_LE_READ_ADV_TX_POWER:
2223 hci_cc_le_read_adv_tx_power(hdev, skb);
2224 break;
2225
Johan Hedberga5c29682011-02-19 12:05:57 -03002226 case HCI_OP_USER_CONFIRM_REPLY:
2227 hci_cc_user_confirm_reply(hdev, skb);
2228 break;
2229
2230 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2231 hci_cc_user_confirm_neg_reply(hdev, skb);
2232 break;
2233
Brian Gix1143d452011-11-23 08:28:34 -08002234 case HCI_OP_USER_PASSKEY_REPLY:
2235 hci_cc_user_passkey_reply(hdev, skb);
2236 break;
2237
2238 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2239 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002240 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002241
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002242 case HCI_OP_LE_SET_ADV_ENABLE:
2243 hci_cc_le_set_adv_enable(hdev, skb);
2244 break;
2245
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002246 case HCI_OP_LE_SET_SCAN_ENABLE:
2247 hci_cc_le_set_scan_enable(hdev, skb);
2248 break;
2249
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002250 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2251 hci_cc_le_read_white_list_size(hdev, skb);
2252 break;
2253
Johan Hedberg9b008c02013-01-22 14:02:01 +02002254 case HCI_OP_LE_READ_SUPPORTED_STATES:
2255 hci_cc_le_read_supported_states(hdev, skb);
2256 break;
2257
Andre Guedesf9b49302011-06-30 19:20:53 -03002258 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2259 hci_cc_write_le_host_supported(hdev, skb);
2260 break;
2261
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002262 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2263 hci_cc_write_remote_amp_assoc(hdev, skb);
2264 break;
2265
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002266 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002267 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002268 break;
2269 }
2270
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002271 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002272 del_timer(&hdev->cmd_timer);
2273
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002274 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002275
Szymon Jancdbccd792012-12-11 08:51:19 +01002276 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002277 atomic_set(&hdev->cmd_cnt, 1);
2278 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002279 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002280 }
2281}
2282
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002283static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002284{
2285 struct hci_ev_cmd_status *ev = (void *) skb->data;
2286 __u16 opcode;
2287
2288 skb_pull(skb, sizeof(*ev));
2289
2290 opcode = __le16_to_cpu(ev->opcode);
2291
2292 switch (opcode) {
2293 case HCI_OP_INQUIRY:
2294 hci_cs_inquiry(hdev, ev->status);
2295 break;
2296
2297 case HCI_OP_CREATE_CONN:
2298 hci_cs_create_conn(hdev, ev->status);
2299 break;
2300
2301 case HCI_OP_ADD_SCO:
2302 hci_cs_add_sco(hdev, ev->status);
2303 break;
2304
Marcel Holtmannf8558552008-07-14 20:13:49 +02002305 case HCI_OP_AUTH_REQUESTED:
2306 hci_cs_auth_requested(hdev, ev->status);
2307 break;
2308
2309 case HCI_OP_SET_CONN_ENCRYPT:
2310 hci_cs_set_conn_encrypt(hdev, ev->status);
2311 break;
2312
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002313 case HCI_OP_REMOTE_NAME_REQ:
2314 hci_cs_remote_name_req(hdev, ev->status);
2315 break;
2316
Marcel Holtmann769be972008-07-14 20:13:49 +02002317 case HCI_OP_READ_REMOTE_FEATURES:
2318 hci_cs_read_remote_features(hdev, ev->status);
2319 break;
2320
2321 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2322 hci_cs_read_remote_ext_features(hdev, ev->status);
2323 break;
2324
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002325 case HCI_OP_SETUP_SYNC_CONN:
2326 hci_cs_setup_sync_conn(hdev, ev->status);
2327 break;
2328
2329 case HCI_OP_SNIFF_MODE:
2330 hci_cs_sniff_mode(hdev, ev->status);
2331 break;
2332
2333 case HCI_OP_EXIT_SNIFF_MODE:
2334 hci_cs_exit_sniff_mode(hdev, ev->status);
2335 break;
2336
Johan Hedberg8962ee72011-01-20 12:40:27 +02002337 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002338 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002339 break;
2340
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002341 case HCI_OP_CREATE_PHY_LINK:
2342 hci_cs_create_phylink(hdev, ev->status);
2343 break;
2344
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002345 case HCI_OP_ACCEPT_PHY_LINK:
2346 hci_cs_accept_phylink(hdev, ev->status);
2347 break;
2348
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002349 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002350 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002351 break;
2352 }
2353
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002354 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002355 del_timer(&hdev->cmd_timer);
2356
Johan Hedberg02350a72013-04-03 21:50:29 +03002357 if (ev->status ||
2358 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2359 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002360
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002361 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002362 atomic_set(&hdev->cmd_cnt, 1);
2363 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002364 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002365 }
2366}
2367
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002368static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002369{
2370 struct hci_ev_role_change *ev = (void *) skb->data;
2371 struct hci_conn *conn;
2372
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002373 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002374
2375 hci_dev_lock(hdev);
2376
2377 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2378 if (conn) {
2379 if (!ev->status) {
2380 if (ev->role)
2381 conn->link_mode &= ~HCI_LM_MASTER;
2382 else
2383 conn->link_mode |= HCI_LM_MASTER;
2384 }
2385
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002386 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002387
2388 hci_role_switch_cfm(conn, ev->status, ev->role);
2389 }
2390
2391 hci_dev_unlock(hdev);
2392}
2393
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002394static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002395{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002396 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002397 int i;
2398
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002399 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2400 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2401 return;
2402 }
2403
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002404 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002405 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002406 BT_DBG("%s bad parameters", hdev->name);
2407 return;
2408 }
2409
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002410 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2411
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002412 for (i = 0; i < ev->num_hndl; i++) {
2413 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002414 struct hci_conn *conn;
2415 __u16 handle, count;
2416
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002417 handle = __le16_to_cpu(info->handle);
2418 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419
2420 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002421 if (!conn)
2422 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002423
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002424 conn->sent -= count;
2425
2426 switch (conn->type) {
2427 case ACL_LINK:
2428 hdev->acl_cnt += count;
2429 if (hdev->acl_cnt > hdev->acl_pkts)
2430 hdev->acl_cnt = hdev->acl_pkts;
2431 break;
2432
2433 case LE_LINK:
2434 if (hdev->le_pkts) {
2435 hdev->le_cnt += count;
2436 if (hdev->le_cnt > hdev->le_pkts)
2437 hdev->le_cnt = hdev->le_pkts;
2438 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002439 hdev->acl_cnt += count;
2440 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441 hdev->acl_cnt = hdev->acl_pkts;
2442 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002443 break;
2444
2445 case SCO_LINK:
2446 hdev->sco_cnt += count;
2447 if (hdev->sco_cnt > hdev->sco_pkts)
2448 hdev->sco_cnt = hdev->sco_pkts;
2449 break;
2450
2451 default:
2452 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2453 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002454 }
2455 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002456
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002457 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002458}
2459
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002460static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2461 __u16 handle)
2462{
2463 struct hci_chan *chan;
2464
2465 switch (hdev->dev_type) {
2466 case HCI_BREDR:
2467 return hci_conn_hash_lookup_handle(hdev, handle);
2468 case HCI_AMP:
2469 chan = hci_chan_lookup_handle(hdev, handle);
2470 if (chan)
2471 return chan->conn;
2472 break;
2473 default:
2474 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2475 break;
2476 }
2477
2478 return NULL;
2479}
2480
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002481static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002482{
2483 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2484 int i;
2485
2486 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2487 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2488 return;
2489 }
2490
2491 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002492 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002493 BT_DBG("%s bad parameters", hdev->name);
2494 return;
2495 }
2496
2497 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002498 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002499
2500 for (i = 0; i < ev->num_hndl; i++) {
2501 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002502 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002503 __u16 handle, block_count;
2504
2505 handle = __le16_to_cpu(info->handle);
2506 block_count = __le16_to_cpu(info->blocks);
2507
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002508 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002509 if (!conn)
2510 continue;
2511
2512 conn->sent -= block_count;
2513
2514 switch (conn->type) {
2515 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002516 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002517 hdev->block_cnt += block_count;
2518 if (hdev->block_cnt > hdev->num_blocks)
2519 hdev->block_cnt = hdev->num_blocks;
2520 break;
2521
2522 default:
2523 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2524 break;
2525 }
2526 }
2527
2528 queue_work(hdev->workqueue, &hdev->tx_work);
2529}
2530
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002531static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002533 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002534 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002535
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002536 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002537
2538 hci_dev_lock(hdev);
2539
Marcel Holtmann04837f62006-07-03 10:02:33 +02002540 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2541 if (conn) {
2542 conn->mode = ev->mode;
2543 conn->interval = __le16_to_cpu(ev->interval);
2544
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002545 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2546 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002547 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002548 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002549 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002550 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002551 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002552
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002553 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002554 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002555 }
2556
2557 hci_dev_unlock(hdev);
2558}
2559
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002560static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002562 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2563 struct hci_conn *conn;
2564
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002565 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002566
2567 hci_dev_lock(hdev);
2568
2569 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002570 if (!conn)
2571 goto unlock;
2572
2573 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002574 hci_conn_hold(conn);
2575 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002576 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002577 }
2578
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002579 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002580 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002581 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002582 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002583 u8 secure;
2584
2585 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2586 secure = 1;
2587 else
2588 secure = 0;
2589
Johan Hedberg744cf192011-11-08 20:40:14 +02002590 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002591 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002592
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002593unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002594 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002595}
2596
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002597static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002598{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002599 struct hci_ev_link_key_req *ev = (void *) skb->data;
2600 struct hci_cp_link_key_reply cp;
2601 struct hci_conn *conn;
2602 struct link_key *key;
2603
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002604 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002605
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002606 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002607 return;
2608
2609 hci_dev_lock(hdev);
2610
2611 key = hci_find_link_key(hdev, &ev->bdaddr);
2612 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002613 BT_DBG("%s link key not found for %pMR", hdev->name,
2614 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002615 goto not_found;
2616 }
2617
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002618 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2619 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002620
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002621 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002622 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002623 BT_DBG("%s ignoring debug key", hdev->name);
2624 goto not_found;
2625 }
2626
2627 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002628 if (conn) {
2629 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002630 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002631 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2632 goto not_found;
2633 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002634
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002635 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002636 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002637 BT_DBG("%s ignoring key unauthenticated for high security",
2638 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002639 goto not_found;
2640 }
2641
2642 conn->key_type = key->type;
2643 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002644 }
2645
2646 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002647 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002648
2649 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2650
2651 hci_dev_unlock(hdev);
2652
2653 return;
2654
2655not_found:
2656 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2657 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658}
2659
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002660static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002661{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002662 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2663 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002664 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002665
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002666 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002667
2668 hci_dev_lock(hdev);
2669
2670 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2671 if (conn) {
2672 hci_conn_hold(conn);
2673 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002674 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002675
2676 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2677 conn->key_type = ev->key_type;
2678
David Herrmann76a68ba2013-04-06 20:28:37 +02002679 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002680 }
2681
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002682 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002683 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002684 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002685
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002686 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002687}
2688
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002689static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002690{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002691 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002692 struct hci_conn *conn;
2693
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002694 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002695
2696 hci_dev_lock(hdev);
2697
2698 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002699 if (conn && !ev->status) {
2700 struct inquiry_entry *ie;
2701
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002702 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2703 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704 ie->data.clock_offset = ev->clock_offset;
2705 ie->timestamp = jiffies;
2706 }
2707 }
2708
2709 hci_dev_unlock(hdev);
2710}
2711
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002712static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002713{
2714 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2715 struct hci_conn *conn;
2716
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002717 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002718
2719 hci_dev_lock(hdev);
2720
2721 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2722 if (conn && !ev->status)
2723 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2724
2725 hci_dev_unlock(hdev);
2726}
2727
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002728static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002729{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002730 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002731 struct inquiry_entry *ie;
2732
2733 BT_DBG("%s", hdev->name);
2734
2735 hci_dev_lock(hdev);
2736
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002737 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2738 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002739 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2740 ie->timestamp = jiffies;
2741 }
2742
2743 hci_dev_unlock(hdev);
2744}
2745
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002746static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2747 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002748{
2749 struct inquiry_data data;
2750 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002751 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002752
2753 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2754
2755 if (!num_rsp)
2756 return;
2757
Andre Guedes1519cc12012-03-21 00:03:38 -03002758 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2759 return;
2760
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002761 hci_dev_lock(hdev);
2762
2763 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002764 struct inquiry_info_with_rssi_and_pscan_mode *info;
2765 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002766
Johan Hedberge17acd42011-03-30 23:57:16 +03002767 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002768 bacpy(&data.bdaddr, &info->bdaddr);
2769 data.pscan_rep_mode = info->pscan_rep_mode;
2770 data.pscan_period_mode = info->pscan_period_mode;
2771 data.pscan_mode = info->pscan_mode;
2772 memcpy(data.dev_class, info->dev_class, 3);
2773 data.clock_offset = info->clock_offset;
2774 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002775 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002776
2777 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002778 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002779 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002780 info->dev_class, info->rssi,
2781 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002782 }
2783 } else {
2784 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2785
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 = 0x00;
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 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002796 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002797 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002798 info->dev_class, info->rssi,
2799 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002800 }
2801 }
2802
2803 hci_dev_unlock(hdev);
2804}
2805
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002806static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2807 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002808{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002809 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2810 struct hci_conn *conn;
2811
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002812 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002813
Marcel Holtmann41a96212008-07-14 20:13:48 +02002814 hci_dev_lock(hdev);
2815
2816 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002817 if (!conn)
2818 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002819
Johan Hedbergcad718e2013-04-17 15:00:51 +03002820 if (ev->page < HCI_MAX_PAGES)
2821 memcpy(conn->features[ev->page], ev->features, 8);
2822
Johan Hedbergccd556f2010-11-10 17:11:51 +02002823 if (!ev->status && ev->page == 0x01) {
2824 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002825
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002826 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2827 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002828 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002829
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302830 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002831 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302832 } else {
2833 /* It is mandatory by the Bluetooth specification that
2834 * Extended Inquiry Results are only used when Secure
2835 * Simple Pairing is enabled, but some devices violate
2836 * this.
2837 *
2838 * To make these devices work, the internal SSP
2839 * enabled flag needs to be cleared if the remote host
2840 * features do not indicate SSP support */
2841 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2842 }
Marcel Holtmann41a96212008-07-14 20:13:48 +02002843 }
2844
Johan Hedbergccd556f2010-11-10 17:11:51 +02002845 if (conn->state != BT_CONFIG)
2846 goto unlock;
2847
Johan Hedberg671267b2012-05-12 16:11:50 -03002848 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002849 struct hci_cp_remote_name_req cp;
2850 memset(&cp, 0, sizeof(cp));
2851 bacpy(&cp.bdaddr, &conn->dst);
2852 cp.pscan_rep_mode = 0x02;
2853 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002854 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2855 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002856 conn->dst_type, 0, NULL, 0,
2857 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002858
Johan Hedberg127178d2010-11-18 22:22:29 +02002859 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002860 conn->state = BT_CONNECTED;
2861 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002862 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002863 }
2864
2865unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002866 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002867}
2868
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002869static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2870 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002871{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002872 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2873 struct hci_conn *conn;
2874
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002875 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002876
2877 hci_dev_lock(hdev);
2878
2879 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002880 if (!conn) {
2881 if (ev->link_type == ESCO_LINK)
2882 goto unlock;
2883
2884 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2885 if (!conn)
2886 goto unlock;
2887
2888 conn->type = SCO_LINK;
2889 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002890
Marcel Holtmann732547f2009-04-19 19:14:14 +02002891 switch (ev->status) {
2892 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002893 conn->handle = __le16_to_cpu(ev->handle);
2894 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002895
2896 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002897 break;
2898
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02002899 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05002900 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002901 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002902 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002903 case 0x1f: /* Unspecified error */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002904 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02002905 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2906 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002907 if (hci_setup_sync(conn, conn->link->handle))
2908 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002909 }
2910 /* fall through */
2911
2912 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002913 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002914 break;
2915 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002916
2917 hci_proto_connect_cfm(conn, ev->status);
2918 if (ev->status)
2919 hci_conn_del(conn);
2920
2921unlock:
2922 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002923}
2924
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002925static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
2926 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002927{
2928 struct inquiry_data data;
2929 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2930 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302931 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002932
2933 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2934
2935 if (!num_rsp)
2936 return;
2937
Andre Guedes1519cc12012-03-21 00:03:38 -03002938 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2939 return;
2940
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002941 hci_dev_lock(hdev);
2942
Johan Hedberge17acd42011-03-30 23:57:16 +03002943 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002944 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002945
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002946 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002947 data.pscan_rep_mode = info->pscan_rep_mode;
2948 data.pscan_period_mode = info->pscan_period_mode;
2949 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002950 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002951 data.clock_offset = info->clock_offset;
2952 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002953 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002954
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002955 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002956 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002957 sizeof(info->data),
2958 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002959 else
2960 name_known = true;
2961
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002962 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002963 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302964 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02002965 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002966 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302967 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002968 }
2969
2970 hci_dev_unlock(hdev);
2971}
2972
Johan Hedberg1c2e0042012-06-08 23:31:13 +08002973static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
2974 struct sk_buff *skb)
2975{
2976 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
2977 struct hci_conn *conn;
2978
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002979 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08002980 __le16_to_cpu(ev->handle));
2981
2982 hci_dev_lock(hdev);
2983
2984 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2985 if (!conn)
2986 goto unlock;
2987
2988 if (!ev->status)
2989 conn->sec_level = conn->pending_sec_level;
2990
2991 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2992
2993 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03002994 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02002995 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08002996 goto unlock;
2997 }
2998
2999 if (conn->state == BT_CONFIG) {
3000 if (!ev->status)
3001 conn->state = BT_CONNECTED;
3002
3003 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003004 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003005 } else {
3006 hci_auth_cfm(conn, ev->status);
3007
3008 hci_conn_hold(conn);
3009 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003010 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003011 }
3012
3013unlock:
3014 hci_dev_unlock(hdev);
3015}
3016
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003017static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003018{
3019 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003020 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3021 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003022 /* If both remote and local IO capabilities allow MITM
3023 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003024 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3025 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3026 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003027 else
Mikel Astizacabae92013-06-28 10:56:28 +02003028 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003029 }
3030
3031 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003032 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3033 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003034 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003035
3036 return conn->auth_type;
3037}
3038
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003039static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003040{
3041 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3042 struct hci_conn *conn;
3043
3044 BT_DBG("%s", hdev->name);
3045
3046 hci_dev_lock(hdev);
3047
3048 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003049 if (!conn)
3050 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003051
Johan Hedberg03b555e2011-01-04 15:40:05 +02003052 hci_conn_hold(conn);
3053
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003054 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003055 goto unlock;
3056
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003057 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003058 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003059 struct hci_cp_io_capability_reply cp;
3060
3061 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303062 /* Change the IO capability from KeyboardDisplay
3063 * to DisplayYesNo as it is not supported by BT spec. */
3064 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003065 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003066 conn->auth_type = hci_get_auth_req(conn);
3067 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003068
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003069 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3070 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003071 cp.oob_data = 0x01;
3072 else
3073 cp.oob_data = 0x00;
3074
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003075 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003076 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003077 } else {
3078 struct hci_cp_io_capability_neg_reply cp;
3079
3080 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003081 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003082
3083 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003084 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003085 }
3086
3087unlock:
3088 hci_dev_unlock(hdev);
3089}
3090
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003091static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003092{
3093 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3094 struct hci_conn *conn;
3095
3096 BT_DBG("%s", hdev->name);
3097
3098 hci_dev_lock(hdev);
3099
3100 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3101 if (!conn)
3102 goto unlock;
3103
Johan Hedberg03b555e2011-01-04 15:40:05 +02003104 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003105 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003106 if (ev->oob_data)
3107 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003108
3109unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003110 hci_dev_unlock(hdev);
3111}
3112
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003113static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3114 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003115{
3116 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003117 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003118 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003119
3120 BT_DBG("%s", hdev->name);
3121
3122 hci_dev_lock(hdev);
3123
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003124 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003125 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003126
Johan Hedberg7a828902011-04-28 11:28:53 -07003127 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3128 if (!conn)
3129 goto unlock;
3130
3131 loc_mitm = (conn->auth_type & 0x01);
3132 rem_mitm = (conn->remote_auth & 0x01);
3133
3134 /* If we require MITM but the remote device can't provide that
3135 * (it has NoInputNoOutput) then reject the confirmation
3136 * request. The only exception is when we're dedicated bonding
3137 * initiators (connect_cfm_cb set) since then we always have the MITM
3138 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003139 if (!conn->connect_cfm_cb && loc_mitm &&
3140 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003141 BT_DBG("Rejecting request: remote device can't provide MITM");
3142 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003143 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003144 goto unlock;
3145 }
3146
3147 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003148 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3149 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003150
3151 /* If we're not the initiators request authorization to
3152 * proceed from user space (mgmt_user_confirm with
3153 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003154 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003155 BT_DBG("Confirming auto-accept as acceptor");
3156 confirm_hint = 1;
3157 goto confirm;
3158 }
3159
Johan Hedberg9f616562011-04-28 11:28:54 -07003160 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003161 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003162
3163 if (hdev->auto_accept_delay > 0) {
3164 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3165 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3166 goto unlock;
3167 }
3168
Johan Hedberg7a828902011-04-28 11:28:53 -07003169 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003170 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003171 goto unlock;
3172 }
3173
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003174confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003175 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003176 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003177
3178unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003179 hci_dev_unlock(hdev);
3180}
3181
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003182static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3183 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003184{
3185 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3186
3187 BT_DBG("%s", hdev->name);
3188
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003189 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003190 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003191}
3192
Johan Hedberg92a25252012-09-06 18:39:26 +03003193static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3194 struct sk_buff *skb)
3195{
3196 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3197 struct hci_conn *conn;
3198
3199 BT_DBG("%s", hdev->name);
3200
3201 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3202 if (!conn)
3203 return;
3204
3205 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3206 conn->passkey_entered = 0;
3207
3208 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3209 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3210 conn->dst_type, conn->passkey_notify,
3211 conn->passkey_entered);
3212}
3213
3214static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3215{
3216 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3217 struct hci_conn *conn;
3218
3219 BT_DBG("%s", hdev->name);
3220
3221 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3222 if (!conn)
3223 return;
3224
3225 switch (ev->type) {
3226 case HCI_KEYPRESS_STARTED:
3227 conn->passkey_entered = 0;
3228 return;
3229
3230 case HCI_KEYPRESS_ENTERED:
3231 conn->passkey_entered++;
3232 break;
3233
3234 case HCI_KEYPRESS_ERASED:
3235 conn->passkey_entered--;
3236 break;
3237
3238 case HCI_KEYPRESS_CLEARED:
3239 conn->passkey_entered = 0;
3240 break;
3241
3242 case HCI_KEYPRESS_COMPLETED:
3243 return;
3244 }
3245
3246 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3247 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3248 conn->dst_type, conn->passkey_notify,
3249 conn->passkey_entered);
3250}
3251
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003252static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3253 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003254{
3255 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3256 struct hci_conn *conn;
3257
3258 BT_DBG("%s", hdev->name);
3259
3260 hci_dev_lock(hdev);
3261
3262 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003263 if (!conn)
3264 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003265
Johan Hedberg2a611692011-02-19 12:06:00 -03003266 /* To avoid duplicate auth_failed events to user space we check
3267 * the HCI_CONN_AUTH_PEND flag which will be set if we
3268 * initiated the authentication. A traditional auth_complete
3269 * event gets always produced as initiator and is also mapped to
3270 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003271 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003272 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003273 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003274
David Herrmann76a68ba2013-04-06 20:28:37 +02003275 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003276
3277unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003278 hci_dev_unlock(hdev);
3279}
3280
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003281static void hci_remote_host_features_evt(struct hci_dev *hdev,
3282 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003283{
3284 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3285 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003286 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003287
3288 BT_DBG("%s", hdev->name);
3289
3290 hci_dev_lock(hdev);
3291
Johan Hedbergcad718e2013-04-17 15:00:51 +03003292 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3293 if (conn)
3294 memcpy(conn->features[1], ev->features, 8);
3295
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003296 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3297 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003298 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003299
3300 hci_dev_unlock(hdev);
3301}
3302
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003303static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3304 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003305{
3306 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3307 struct oob_data *data;
3308
3309 BT_DBG("%s", hdev->name);
3310
3311 hci_dev_lock(hdev);
3312
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003313 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003314 goto unlock;
3315
Szymon Janc2763eda2011-03-22 13:12:22 +01003316 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3317 if (data) {
3318 struct hci_cp_remote_oob_data_reply cp;
3319
3320 bacpy(&cp.bdaddr, &ev->bdaddr);
3321 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3322 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3323
3324 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003325 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003326 } else {
3327 struct hci_cp_remote_oob_data_neg_reply cp;
3328
3329 bacpy(&cp.bdaddr, &ev->bdaddr);
3330 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003331 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003332 }
3333
Szymon Jance1ba1f12011-04-06 13:01:59 +02003334unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003335 hci_dev_unlock(hdev);
3336}
3337
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003338static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3339 struct sk_buff *skb)
3340{
3341 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3342 struct hci_conn *hcon, *bredr_hcon;
3343
3344 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3345 ev->status);
3346
3347 hci_dev_lock(hdev);
3348
3349 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3350 if (!hcon) {
3351 hci_dev_unlock(hdev);
3352 return;
3353 }
3354
3355 if (ev->status) {
3356 hci_conn_del(hcon);
3357 hci_dev_unlock(hdev);
3358 return;
3359 }
3360
3361 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3362
3363 hcon->state = BT_CONNECTED;
3364 bacpy(&hcon->dst, &bredr_hcon->dst);
3365
3366 hci_conn_hold(hcon);
3367 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003368 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003369
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003370 hci_conn_add_sysfs(hcon);
3371
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003372 amp_physical_cfm(bredr_hcon, hcon);
3373
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003374 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003375}
3376
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003377static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3378{
3379 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3380 struct hci_conn *hcon;
3381 struct hci_chan *hchan;
3382 struct amp_mgr *mgr;
3383
3384 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3385 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3386 ev->status);
3387
3388 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3389 if (!hcon)
3390 return;
3391
3392 /* Create AMP hchan */
3393 hchan = hci_chan_create(hcon);
3394 if (!hchan)
3395 return;
3396
3397 hchan->handle = le16_to_cpu(ev->handle);
3398
3399 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3400
3401 mgr = hcon->amp_mgr;
3402 if (mgr && mgr->bredr_chan) {
3403 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3404
3405 l2cap_chan_lock(bredr_chan);
3406
3407 bredr_chan->conn->mtu = hdev->block_mtu;
3408 l2cap_logical_cfm(bredr_chan, hchan, 0);
3409 hci_conn_hold(hcon);
3410
3411 l2cap_chan_unlock(bredr_chan);
3412 }
3413}
3414
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003415static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3416 struct sk_buff *skb)
3417{
3418 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3419 struct hci_chan *hchan;
3420
3421 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3422 le16_to_cpu(ev->handle), ev->status);
3423
3424 if (ev->status)
3425 return;
3426
3427 hci_dev_lock(hdev);
3428
3429 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3430 if (!hchan)
3431 goto unlock;
3432
3433 amp_destroy_logical_link(hchan, ev->reason);
3434
3435unlock:
3436 hci_dev_unlock(hdev);
3437}
3438
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003439static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3440 struct sk_buff *skb)
3441{
3442 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3443 struct hci_conn *hcon;
3444
3445 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3446
3447 if (ev->status)
3448 return;
3449
3450 hci_dev_lock(hdev);
3451
3452 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3453 if (hcon) {
3454 hcon->state = BT_CLOSED;
3455 hci_conn_del(hcon);
3456 }
3457
3458 hci_dev_unlock(hdev);
3459}
3460
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003461static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003462{
3463 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3464 struct hci_conn *conn;
3465
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003466 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003467
3468 hci_dev_lock(hdev);
3469
Andre Guedesb47a09b2012-07-27 15:10:15 -03003470 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003471 if (!conn) {
3472 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3473 if (!conn) {
3474 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003475 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003476 }
Andre Guedes29b79882011-05-31 14:20:54 -03003477
3478 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003479
3480 if (ev->role == LE_CONN_ROLE_MASTER) {
3481 conn->out = true;
3482 conn->link_mode |= HCI_LM_MASTER;
3483 }
Ville Tervob62f3282011-02-10 22:38:50 -03003484 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003485
Andre Guedescd17dec2012-07-27 15:10:16 -03003486 if (ev->status) {
3487 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3488 conn->dst_type, ev->status);
3489 hci_proto_connect_cfm(conn, ev->status);
3490 conn->state = BT_CLOSED;
3491 hci_conn_del(conn);
3492 goto unlock;
3493 }
3494
Johan Hedbergb644ba32012-01-17 21:48:47 +02003495 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3496 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003497 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003498
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003499 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003500 conn->handle = __le16_to_cpu(ev->handle);
3501 conn->state = BT_CONNECTED;
3502
Ville Tervofcd89c02011-02-10 22:38:47 -03003503 hci_conn_add_sysfs(conn);
3504
3505 hci_proto_connect_cfm(conn, ev->status);
3506
3507unlock:
3508 hci_dev_unlock(hdev);
3509}
3510
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003511static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003512{
Andre Guedese95beb42011-09-26 20:48:35 -03003513 u8 num_reports = skb->data[0];
3514 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003515 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003516
Andre Guedese95beb42011-09-26 20:48:35 -03003517 while (num_reports--) {
3518 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003519
Andre Guedes3c9e9192012-01-10 18:20:50 -03003520 rssi = ev->data[ev->length];
3521 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003522 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003523
Andre Guedese95beb42011-09-26 20:48:35 -03003524 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003525 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003526}
3527
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003528static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003529{
3530 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3531 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003532 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003533 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003534 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003535
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003536 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003537
3538 hci_dev_lock(hdev);
3539
3540 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003541 if (conn == NULL)
3542 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003543
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003544 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3545 if (ltk == NULL)
3546 goto not_found;
3547
3548 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003549 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003550
3551 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03003552 conn->pending_sec_level = BT_SECURITY_HIGH;
3553 else
3554 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003555
Andre Guedes89cbb4d2013-07-31 16:25:29 -03003556 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003557
3558 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3559
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003560 if (ltk->type & HCI_SMP_STK) {
3561 list_del(&ltk->list);
3562 kfree(ltk);
3563 }
3564
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003565 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003566
3567 return;
3568
3569not_found:
3570 neg.handle = ev->handle;
3571 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3572 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003573}
3574
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003575static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003576{
3577 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3578
3579 skb_pull(skb, sizeof(*le_ev));
3580
3581 switch (le_ev->subevent) {
3582 case HCI_EV_LE_CONN_COMPLETE:
3583 hci_le_conn_complete_evt(hdev, skb);
3584 break;
3585
Andre Guedes9aa04c92011-05-26 16:23:51 -03003586 case HCI_EV_LE_ADVERTISING_REPORT:
3587 hci_le_adv_report_evt(hdev, skb);
3588 break;
3589
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003590 case HCI_EV_LE_LTK_REQ:
3591 hci_le_ltk_request_evt(hdev, skb);
3592 break;
3593
Ville Tervofcd89c02011-02-10 22:38:47 -03003594 default:
3595 break;
3596 }
3597}
3598
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003599static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3600{
3601 struct hci_ev_channel_selected *ev = (void *) skb->data;
3602 struct hci_conn *hcon;
3603
3604 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3605
3606 skb_pull(skb, sizeof(*ev));
3607
3608 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3609 if (!hcon)
3610 return;
3611
3612 amp_read_loc_assoc_final_data(hdev, hcon);
3613}
3614
Linus Torvalds1da177e2005-04-16 15:20:36 -07003615void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3616{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003617 struct hci_event_hdr *hdr = (void *) skb->data;
3618 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003619
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003620 hci_dev_lock(hdev);
3621
3622 /* Received events are (currently) only needed when a request is
3623 * ongoing so avoid unnecessary memory allocation.
3624 */
3625 if (hdev->req_status == HCI_REQ_PEND) {
3626 kfree_skb(hdev->recv_evt);
3627 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3628 }
3629
3630 hci_dev_unlock(hdev);
3631
Linus Torvalds1da177e2005-04-16 15:20:36 -07003632 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3633
Johan Hedberg02350a72013-04-03 21:50:29 +03003634 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02003635 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
3636 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03003637
3638 hci_req_cmd_complete(hdev, opcode, 0);
3639 }
3640
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003641 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003642 case HCI_EV_INQUIRY_COMPLETE:
3643 hci_inquiry_complete_evt(hdev, skb);
3644 break;
3645
3646 case HCI_EV_INQUIRY_RESULT:
3647 hci_inquiry_result_evt(hdev, skb);
3648 break;
3649
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003650 case HCI_EV_CONN_COMPLETE:
3651 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003652 break;
3653
Linus Torvalds1da177e2005-04-16 15:20:36 -07003654 case HCI_EV_CONN_REQUEST:
3655 hci_conn_request_evt(hdev, skb);
3656 break;
3657
Linus Torvalds1da177e2005-04-16 15:20:36 -07003658 case HCI_EV_DISCONN_COMPLETE:
3659 hci_disconn_complete_evt(hdev, skb);
3660 break;
3661
Linus Torvalds1da177e2005-04-16 15:20:36 -07003662 case HCI_EV_AUTH_COMPLETE:
3663 hci_auth_complete_evt(hdev, skb);
3664 break;
3665
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003666 case HCI_EV_REMOTE_NAME:
3667 hci_remote_name_evt(hdev, skb);
3668 break;
3669
Linus Torvalds1da177e2005-04-16 15:20:36 -07003670 case HCI_EV_ENCRYPT_CHANGE:
3671 hci_encrypt_change_evt(hdev, skb);
3672 break;
3673
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003674 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3675 hci_change_link_key_complete_evt(hdev, skb);
3676 break;
3677
3678 case HCI_EV_REMOTE_FEATURES:
3679 hci_remote_features_evt(hdev, skb);
3680 break;
3681
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003682 case HCI_EV_CMD_COMPLETE:
3683 hci_cmd_complete_evt(hdev, skb);
3684 break;
3685
3686 case HCI_EV_CMD_STATUS:
3687 hci_cmd_status_evt(hdev, skb);
3688 break;
3689
3690 case HCI_EV_ROLE_CHANGE:
3691 hci_role_change_evt(hdev, skb);
3692 break;
3693
3694 case HCI_EV_NUM_COMP_PKTS:
3695 hci_num_comp_pkts_evt(hdev, skb);
3696 break;
3697
3698 case HCI_EV_MODE_CHANGE:
3699 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003700 break;
3701
3702 case HCI_EV_PIN_CODE_REQ:
3703 hci_pin_code_request_evt(hdev, skb);
3704 break;
3705
3706 case HCI_EV_LINK_KEY_REQ:
3707 hci_link_key_request_evt(hdev, skb);
3708 break;
3709
3710 case HCI_EV_LINK_KEY_NOTIFY:
3711 hci_link_key_notify_evt(hdev, skb);
3712 break;
3713
3714 case HCI_EV_CLOCK_OFFSET:
3715 hci_clock_offset_evt(hdev, skb);
3716 break;
3717
Marcel Holtmanna8746412008-07-14 20:13:46 +02003718 case HCI_EV_PKT_TYPE_CHANGE:
3719 hci_pkt_type_change_evt(hdev, skb);
3720 break;
3721
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003722 case HCI_EV_PSCAN_REP_MODE:
3723 hci_pscan_rep_mode_evt(hdev, skb);
3724 break;
3725
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003726 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3727 hci_inquiry_result_with_rssi_evt(hdev, skb);
3728 break;
3729
3730 case HCI_EV_REMOTE_EXT_FEATURES:
3731 hci_remote_ext_features_evt(hdev, skb);
3732 break;
3733
3734 case HCI_EV_SYNC_CONN_COMPLETE:
3735 hci_sync_conn_complete_evt(hdev, skb);
3736 break;
3737
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003738 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3739 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003740 break;
3741
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003742 case HCI_EV_KEY_REFRESH_COMPLETE:
3743 hci_key_refresh_complete_evt(hdev, skb);
3744 break;
3745
Marcel Holtmann04936842008-07-14 20:13:48 +02003746 case HCI_EV_IO_CAPA_REQUEST:
3747 hci_io_capa_request_evt(hdev, skb);
3748 break;
3749
Johan Hedberg03b555e2011-01-04 15:40:05 +02003750 case HCI_EV_IO_CAPA_REPLY:
3751 hci_io_capa_reply_evt(hdev, skb);
3752 break;
3753
Johan Hedberga5c29682011-02-19 12:05:57 -03003754 case HCI_EV_USER_CONFIRM_REQUEST:
3755 hci_user_confirm_request_evt(hdev, skb);
3756 break;
3757
Brian Gix1143d452011-11-23 08:28:34 -08003758 case HCI_EV_USER_PASSKEY_REQUEST:
3759 hci_user_passkey_request_evt(hdev, skb);
3760 break;
3761
Johan Hedberg92a25252012-09-06 18:39:26 +03003762 case HCI_EV_USER_PASSKEY_NOTIFY:
3763 hci_user_passkey_notify_evt(hdev, skb);
3764 break;
3765
3766 case HCI_EV_KEYPRESS_NOTIFY:
3767 hci_keypress_notify_evt(hdev, skb);
3768 break;
3769
Marcel Holtmann04936842008-07-14 20:13:48 +02003770 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3771 hci_simple_pair_complete_evt(hdev, skb);
3772 break;
3773
Marcel Holtmann41a96212008-07-14 20:13:48 +02003774 case HCI_EV_REMOTE_HOST_FEATURES:
3775 hci_remote_host_features_evt(hdev, skb);
3776 break;
3777
Ville Tervofcd89c02011-02-10 22:38:47 -03003778 case HCI_EV_LE_META:
3779 hci_le_meta_evt(hdev, skb);
3780 break;
3781
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003782 case HCI_EV_CHANNEL_SELECTED:
3783 hci_chan_selected_evt(hdev, skb);
3784 break;
3785
Szymon Janc2763eda2011-03-22 13:12:22 +01003786 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3787 hci_remote_oob_data_request_evt(hdev, skb);
3788 break;
3789
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003790 case HCI_EV_PHY_LINK_COMPLETE:
3791 hci_phy_link_complete_evt(hdev, skb);
3792 break;
3793
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003794 case HCI_EV_LOGICAL_LINK_COMPLETE:
3795 hci_loglink_complete_evt(hdev, skb);
3796 break;
3797
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003798 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3799 hci_disconn_loglink_complete_evt(hdev, skb);
3800 break;
3801
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003802 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3803 hci_disconn_phylink_complete_evt(hdev, skb);
3804 break;
3805
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003806 case HCI_EV_NUM_COMP_BLOCKS:
3807 hci_num_comp_blocks_evt(hdev, skb);
3808 break;
3809
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003810 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003811 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003812 break;
3813 }
3814
3815 kfree_skb(skb);
3816 hdev->stat.evt_rx++;
3817}