blob: 7450626b77049bb5416fb82fa5f27a40acf4dbeb [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 Hedberg36f7fc72011-11-04 00:17:45 +0200313 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200314 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200315
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200316 if (param & SCAN_PAGE) {
317 set_bit(HCI_PSCAN, &hdev->flags);
318 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200319 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200320 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200321 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200322
323done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200324 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200325}
326
327static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
328{
329 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
330
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300331 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200332
333 if (rp->status)
334 return;
335
336 memcpy(hdev->dev_class, rp->dev_class, 3);
337
338 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300339 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200340}
341
342static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
343{
344 __u8 status = *((__u8 *) skb->data);
345 void *sent;
346
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300347 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200348
349 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
350 if (!sent)
351 return;
352
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100353 hci_dev_lock(hdev);
354
355 if (status == 0)
356 memcpy(hdev->dev_class, sent, 3);
357
358 if (test_bit(HCI_MGMT, &hdev->dev_flags))
359 mgmt_set_class_of_dev_complete(hdev, sent, status);
360
361 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200362}
363
364static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
365{
366 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200368
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300369 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200370
371 if (rp->status)
372 return;
373
374 setting = __le16_to_cpu(rp->voice_setting);
375
Marcel Holtmannf383f272008-07-14 20:13:47 +0200376 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200377 return;
378
379 hdev->voice_setting = setting;
380
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300381 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200382
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200383 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200384 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200385}
386
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300387static void hci_cc_write_voice_setting(struct hci_dev *hdev,
388 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389{
390 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200391 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 void *sent;
393
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300394 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395
Marcel Holtmannf383f272008-07-14 20:13:47 +0200396 if (status)
397 return;
398
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200399 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
400 if (!sent)
401 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
Marcel Holtmannf383f272008-07-14 20:13:47 +0200403 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404
Marcel Holtmannf383f272008-07-14 20:13:47 +0200405 if (hdev->voice_setting == setting)
406 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
Marcel Holtmannf383f272008-07-14 20:13:47 +0200408 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300410 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200411
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200412 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200413 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414}
415
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -0700416static void hci_cc_read_num_supported_iac(struct hci_dev *hdev,
417 struct sk_buff *skb)
418{
419 struct hci_rp_read_num_supported_iac *rp = (void *) skb->data;
420
421 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
422
423 if (rp->status)
424 return;
425
426 hdev->num_iac = rp->num_iac;
427
428 BT_DBG("%s num iac %d", hdev->name, hdev->num_iac);
429}
430
Marcel Holtmann333140b2008-07-14 20:13:48 +0200431static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
432{
433 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300434 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200435
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300436 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200437
Marcel Holtmann333140b2008-07-14 20:13:48 +0200438 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
439 if (!sent)
440 return;
441
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300442 if (!status) {
443 if (sent->mode)
Johan Hedbergcad718e2013-04-17 15:00:51 +0300444 hdev->features[1][0] |= LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300445 else
Johan Hedbergcad718e2013-04-17 15:00:51 +0300446 hdev->features[1][0] &= ~LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300447 }
448
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200449 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300450 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200451 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300452 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200453 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
454 else
455 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
456 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200457}
458
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200459static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
460{
461 struct hci_rp_read_local_version *rp = (void *) skb->data;
462
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300463 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200464
465 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200466 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200467
468 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200469 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200470 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200471 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200472 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200473
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300474 BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300475 hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200476}
477
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300478static void hci_cc_read_local_commands(struct hci_dev *hdev,
479 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200480{
481 struct hci_rp_read_local_commands *rp = (void *) skb->data;
482
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300483 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200484
Johan Hedberg2177bab2013-03-05 20:37:43 +0200485 if (!rp->status)
486 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200487}
488
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300489static void hci_cc_read_local_features(struct hci_dev *hdev,
490 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200491{
492 struct hci_rp_read_local_features *rp = (void *) skb->data;
493
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300494 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200495
496 if (rp->status)
497 return;
498
499 memcpy(hdev->features, rp->features, 8);
500
501 /* Adjust default settings according to features
502 * supported by device. */
503
Johan Hedbergcad718e2013-04-17 15:00:51 +0300504 if (hdev->features[0][0] & LMP_3SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200505 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
506
Johan Hedbergcad718e2013-04-17 15:00:51 +0300507 if (hdev->features[0][0] & LMP_5SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200508 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
509
Johan Hedbergcad718e2013-04-17 15:00:51 +0300510 if (hdev->features[0][1] & LMP_HV2) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200511 hdev->pkt_type |= (HCI_HV2);
512 hdev->esco_type |= (ESCO_HV2);
513 }
514
Johan Hedbergcad718e2013-04-17 15:00:51 +0300515 if (hdev->features[0][1] & LMP_HV3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200516 hdev->pkt_type |= (HCI_HV3);
517 hdev->esco_type |= (ESCO_HV3);
518 }
519
Andre Guedes45db810f2012-07-24 15:03:49 -0300520 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200521 hdev->esco_type |= (ESCO_EV3);
522
Johan Hedbergcad718e2013-04-17 15:00:51 +0300523 if (hdev->features[0][4] & LMP_EV4)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200524 hdev->esco_type |= (ESCO_EV4);
525
Johan Hedbergcad718e2013-04-17 15:00:51 +0300526 if (hdev->features[0][4] & LMP_EV5)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200527 hdev->esco_type |= (ESCO_EV5);
528
Johan Hedbergcad718e2013-04-17 15:00:51 +0300529 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100530 hdev->esco_type |= (ESCO_2EV3);
531
Johan Hedbergcad718e2013-04-17 15:00:51 +0300532 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100533 hdev->esco_type |= (ESCO_3EV3);
534
Johan Hedbergcad718e2013-04-17 15:00:51 +0300535 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100536 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
537
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200538 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
Johan Hedbergcad718e2013-04-17 15:00:51 +0300539 hdev->features[0][0], hdev->features[0][1],
540 hdev->features[0][2], hdev->features[0][3],
541 hdev->features[0][4], hdev->features[0][5],
542 hdev->features[0][6], hdev->features[0][7]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200543}
544
Andre Guedes971e3a42011-06-30 19:20:52 -0300545static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300546 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300547{
548 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
549
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300550 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300551
552 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200553 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300554
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300555 hdev->max_page = rp->max_page;
556
Johan Hedbergcad718e2013-04-17 15:00:51 +0300557 if (rp->page < HCI_MAX_PAGES)
558 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300559}
560
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200561static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300562 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200563{
564 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
565
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300566 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200567
Johan Hedberg42c6b122013-03-05 20:37:49 +0200568 if (!rp->status)
569 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200570}
571
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200572static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
573{
574 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
575
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300576 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200577
578 if (rp->status)
579 return;
580
581 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
582 hdev->sco_mtu = rp->sco_mtu;
583 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
584 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
585
586 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
587 hdev->sco_mtu = 64;
588 hdev->sco_pkts = 8;
589 }
590
591 hdev->acl_cnt = hdev->acl_pkts;
592 hdev->sco_cnt = hdev->sco_pkts;
593
Gustavo Padovan807deac2012-05-17 00:36:24 -0300594 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
595 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200596}
597
598static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
599{
600 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
601
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300602 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200603
604 if (!rp->status)
605 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200606}
607
Johan Hedbergf332ec62013-03-15 17:07:11 -0500608static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
609 struct sk_buff *skb)
610{
611 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
612
613 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
614
615 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
616 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
617 hdev->page_scan_window = __le16_to_cpu(rp->window);
618 }
619}
620
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500621static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
622 struct sk_buff *skb)
623{
624 u8 status = *((u8 *) skb->data);
625 struct hci_cp_write_page_scan_activity *sent;
626
627 BT_DBG("%s status 0x%2.2x", hdev->name, status);
628
629 if (status)
630 return;
631
632 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
633 if (!sent)
634 return;
635
636 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
637 hdev->page_scan_window = __le16_to_cpu(sent->window);
638}
639
Johan Hedbergf332ec62013-03-15 17:07:11 -0500640static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
641 struct sk_buff *skb)
642{
643 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
644
645 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
646
647 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
648 hdev->page_scan_type = rp->type;
649}
650
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500651static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
652 struct sk_buff *skb)
653{
654 u8 status = *((u8 *) skb->data);
655 u8 *type;
656
657 BT_DBG("%s status 0x%2.2x", hdev->name, status);
658
659 if (status)
660 return;
661
662 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
663 if (type)
664 hdev->page_scan_type = *type;
665}
666
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200667static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300668 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200669{
670 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
671
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300672 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200673
674 if (rp->status)
675 return;
676
677 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
678 hdev->block_len = __le16_to_cpu(rp->block_len);
679 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
680
681 hdev->block_cnt = hdev->num_blocks;
682
683 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300684 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200685}
686
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300687static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300688 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300689{
690 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
691
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300692 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300693
694 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300695 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300696
697 hdev->amp_status = rp->amp_status;
698 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
699 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
700 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
701 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
702 hdev->amp_type = rp->amp_type;
703 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
704 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
705 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
706 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
707
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300708a2mp_rsp:
709 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300710}
711
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300712static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
713 struct sk_buff *skb)
714{
715 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
716 struct amp_assoc *assoc = &hdev->loc_assoc;
717 size_t rem_len, frag_len;
718
719 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
720
721 if (rp->status)
722 goto a2mp_rsp;
723
724 frag_len = skb->len - sizeof(*rp);
725 rem_len = __le16_to_cpu(rp->rem_len);
726
727 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300728 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300729
730 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
731 assoc->offset += frag_len;
732
733 /* Read other fragments */
734 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
735
736 return;
737 }
738
739 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
740 assoc->len = assoc->offset + rem_len;
741 assoc->offset = 0;
742
743a2mp_rsp:
744 /* Send A2MP Rsp when all fragments are received */
745 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300746 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300747}
748
Johan Hedbergd5859e22011-01-25 01:19:58 +0200749static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300750 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200751{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700752 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200753
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300754 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200755
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700756 if (!rp->status)
757 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200758}
759
Johan Hedberg980e1a52011-01-22 06:10:07 +0200760static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
761{
762 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
763 struct hci_cp_pin_code_reply *cp;
764 struct hci_conn *conn;
765
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300766 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200767
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200768 hci_dev_lock(hdev);
769
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200770 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200771 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200772
Mikel Astizfa1bd912012-08-09 09:52:29 +0200773 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200774 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200775
776 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
777 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200778 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200779
780 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
781 if (conn)
782 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200783
784unlock:
785 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200786}
787
788static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
789{
790 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
791
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300792 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200793
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200794 hci_dev_lock(hdev);
795
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200796 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200797 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300798 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200799
800 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200801}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200802
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300803static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
804 struct sk_buff *skb)
805{
806 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
807
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300808 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300809
810 if (rp->status)
811 return;
812
813 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
814 hdev->le_pkts = rp->le_max_pkt;
815
816 hdev->le_cnt = hdev->le_pkts;
817
818 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300819}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200820
Johan Hedberg60e77322013-01-22 14:01:59 +0200821static void hci_cc_le_read_local_features(struct hci_dev *hdev,
822 struct sk_buff *skb)
823{
824 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
825
826 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
827
828 if (!rp->status)
829 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200830}
831
Johan Hedberg8fa19092012-10-19 20:57:49 +0300832static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
833 struct sk_buff *skb)
834{
835 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
836
837 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
838
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500839 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300840 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300841}
842
Johan Hedberga5c29682011-02-19 12:05:57 -0300843static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
844{
845 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
846
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300847 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300848
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200849 hci_dev_lock(hdev);
850
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200851 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300852 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
853 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200854
855 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300856}
857
858static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300859 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300860{
861 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
862
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300863 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300864
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200865 hci_dev_lock(hdev);
866
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200867 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200868 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300869 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200870
871 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300872}
873
Brian Gix1143d452011-11-23 08:28:34 -0800874static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
875{
876 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
877
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300878 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800879
880 hci_dev_lock(hdev);
881
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200882 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200883 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300884 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800885
886 hci_dev_unlock(hdev);
887}
888
889static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300890 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800891{
892 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
893
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300894 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800895
896 hci_dev_lock(hdev);
897
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200898 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800899 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300900 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800901
902 hci_dev_unlock(hdev);
903}
904
Szymon Jancc35938b2011-03-22 13:12:21 +0100905static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300906 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100907{
908 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
909
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300910 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100911
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200912 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +0200913 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +0100914 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200915 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100916}
917
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100918static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
919{
920 __u8 *sent, status = *((__u8 *) skb->data);
921
922 BT_DBG("%s status 0x%2.2x", hdev->name, status);
923
924 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
925 if (!sent)
926 return;
927
928 hci_dev_lock(hdev);
929
930 if (!status) {
931 if (*sent)
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200932 set_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100933 else
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200934 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100935 }
936
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500937 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100938}
939
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300940static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300941 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300942{
943 struct hci_cp_le_set_scan_enable *cp;
944 __u8 status = *((__u8 *) skb->data);
945
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300946 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300947
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300948 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
949 if (!cp)
950 return;
951
Andre Guedes3fd319b2013-04-30 15:29:36 -0300952 if (status)
953 return;
954
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200955 switch (cp->enable) {
Andre Guedes76a388be2013-04-04 20:21:02 -0300956 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300957 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200958 break;
959
Andre Guedes76a388be2013-04-04 20:21:02 -0300960 case LE_SCAN_DISABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300961 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200962 break;
963
964 default:
965 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
966 break;
Andre Guedes35815082011-05-26 16:23:53 -0300967 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300968}
969
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200970static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
971 struct sk_buff *skb)
972{
973 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
974
975 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
976
977 if (!rp->status)
978 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200979}
980
Johan Hedberg9b008c02013-01-22 14:02:01 +0200981static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
982 struct sk_buff *skb)
983{
984 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
985
986 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
987
988 if (!rp->status)
989 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +0200990}
991
Gustavo Padovan6039aa72012-05-23 04:04:18 -0300992static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
993 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -0300994{
Johan Hedberg06199cf2012-02-22 16:37:11 +0200995 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -0300996 __u8 status = *((__u8 *) skb->data);
997
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300998 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -0300999
Johan Hedberg06199cf2012-02-22 16:37:11 +02001000 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001001 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001002 return;
1003
Johan Hedberg8f984df2012-02-28 01:07:22 +02001004 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001005 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001006 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001007 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1008 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001009 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001010 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001011 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001012 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001013
1014 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001015 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001016 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001017 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001018 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001019}
1020
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001021static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1022 struct sk_buff *skb)
1023{
1024 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1025
1026 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1027 hdev->name, rp->status, rp->phy_handle);
1028
1029 if (rp->status)
1030 return;
1031
1032 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1033}
1034
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001035static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001036{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001037 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001038
1039 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001040 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001041 return;
1042 }
1043
Andre Guedes89352e72011-11-04 14:16:53 -03001044 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001045}
1046
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001047static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001049 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001052 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001053
1054 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 if (!cp)
1056 return;
1057
1058 hci_dev_lock(hdev);
1059
1060 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1061
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001062 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063
1064 if (status) {
1065 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001066 if (status != 0x0c || conn->attempt > 2) {
1067 conn->state = BT_CLOSED;
1068 hci_proto_connect_cfm(conn, status);
1069 hci_conn_del(conn);
1070 } else
1071 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072 }
1073 } else {
1074 if (!conn) {
1075 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1076 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001077 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078 conn->link_mode |= HCI_LM_MASTER;
1079 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001080 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081 }
1082 }
1083
1084 hci_dev_unlock(hdev);
1085}
1086
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001087static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001089 struct hci_cp_add_sco *cp;
1090 struct hci_conn *acl, *sco;
1091 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001093 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001094
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001095 if (!status)
1096 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001098 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1099 if (!cp)
1100 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001102 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001104 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001105
1106 hci_dev_lock(hdev);
1107
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001108 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001109 if (acl) {
1110 sco = acl->link;
1111 if (sco) {
1112 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001113
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001114 hci_proto_connect_cfm(sco, status);
1115 hci_conn_del(sco);
1116 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001117 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001118
1119 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120}
1121
Marcel Holtmannf8558552008-07-14 20:13:49 +02001122static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1123{
1124 struct hci_cp_auth_requested *cp;
1125 struct hci_conn *conn;
1126
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001127 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001128
1129 if (!status)
1130 return;
1131
1132 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1133 if (!cp)
1134 return;
1135
1136 hci_dev_lock(hdev);
1137
1138 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1139 if (conn) {
1140 if (conn->state == BT_CONFIG) {
1141 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001142 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001143 }
1144 }
1145
1146 hci_dev_unlock(hdev);
1147}
1148
1149static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1150{
1151 struct hci_cp_set_conn_encrypt *cp;
1152 struct hci_conn *conn;
1153
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001154 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001155
1156 if (!status)
1157 return;
1158
1159 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1160 if (!cp)
1161 return;
1162
1163 hci_dev_lock(hdev);
1164
1165 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1166 if (conn) {
1167 if (conn->state == BT_CONFIG) {
1168 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001169 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001170 }
1171 }
1172
1173 hci_dev_unlock(hdev);
1174}
1175
Johan Hedberg127178d2010-11-18 22:22:29 +02001176static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001177 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001178{
Johan Hedberg392599b2010-11-18 22:22:28 +02001179 if (conn->state != BT_CONFIG || !conn->out)
1180 return 0;
1181
Johan Hedberg765c2a92011-01-19 12:06:52 +05301182 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001183 return 0;
1184
1185 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001186 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001187 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1188 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001189 return 0;
1190
Johan Hedberg392599b2010-11-18 22:22:28 +02001191 return 1;
1192}
1193
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001194static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001195 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001196{
1197 struct hci_cp_remote_name_req cp;
1198
1199 memset(&cp, 0, sizeof(cp));
1200
1201 bacpy(&cp.bdaddr, &e->data.bdaddr);
1202 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1203 cp.pscan_mode = e->data.pscan_mode;
1204 cp.clock_offset = e->data.clock_offset;
1205
1206 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1207}
1208
Johan Hedbergb644ba32012-01-17 21:48:47 +02001209static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001210{
1211 struct discovery_state *discov = &hdev->discovery;
1212 struct inquiry_entry *e;
1213
Johan Hedbergb644ba32012-01-17 21:48:47 +02001214 if (list_empty(&discov->resolve))
1215 return false;
1216
1217 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001218 if (!e)
1219 return false;
1220
Johan Hedbergb644ba32012-01-17 21:48:47 +02001221 if (hci_resolve_name(hdev, e) == 0) {
1222 e->name_state = NAME_PENDING;
1223 return true;
1224 }
1225
1226 return false;
1227}
1228
1229static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001230 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001231{
1232 struct discovery_state *discov = &hdev->discovery;
1233 struct inquiry_entry *e;
1234
1235 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001236 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1237 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001238
1239 if (discov->state == DISCOVERY_STOPPED)
1240 return;
1241
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001242 if (discov->state == DISCOVERY_STOPPING)
1243 goto discov_complete;
1244
1245 if (discov->state != DISCOVERY_RESOLVING)
1246 return;
1247
1248 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001249 /* If the device was not found in a list of found devices names of which
1250 * are pending. there is no need to continue resolving a next name as it
1251 * will be done upon receiving another Remote Name Request Complete
1252 * Event */
1253 if (!e)
1254 return;
1255
1256 list_del(&e->list);
1257 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001258 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001259 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1260 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001261 } else {
1262 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001263 }
1264
Johan Hedbergb644ba32012-01-17 21:48:47 +02001265 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001266 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001267
1268discov_complete:
1269 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1270}
1271
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001272static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1273{
Johan Hedberg127178d2010-11-18 22:22:29 +02001274 struct hci_cp_remote_name_req *cp;
1275 struct hci_conn *conn;
1276
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001277 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001278
1279 /* If successful wait for the name req complete event before
1280 * checking for the need to do authentication */
1281 if (!status)
1282 return;
1283
1284 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1285 if (!cp)
1286 return;
1287
1288 hci_dev_lock(hdev);
1289
1290 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001291
1292 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1293 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1294
Johan Hedberg79c6c702011-04-28 11:28:55 -07001295 if (!conn)
1296 goto unlock;
1297
1298 if (!hci_outgoing_auth_needed(hdev, conn))
1299 goto unlock;
1300
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001301 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001302 struct hci_cp_auth_requested auth_cp;
1303
1304 auth_cp.handle = __cpu_to_le16(conn->handle);
1305 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1306 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001307 }
1308
Johan Hedberg79c6c702011-04-28 11:28:55 -07001309unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001310 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001311}
1312
Marcel Holtmann769be972008-07-14 20:13:49 +02001313static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1314{
1315 struct hci_cp_read_remote_features *cp;
1316 struct hci_conn *conn;
1317
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001318 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001319
1320 if (!status)
1321 return;
1322
1323 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1324 if (!cp)
1325 return;
1326
1327 hci_dev_lock(hdev);
1328
1329 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1330 if (conn) {
1331 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001332 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001333 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001334 }
1335 }
1336
1337 hci_dev_unlock(hdev);
1338}
1339
1340static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1341{
1342 struct hci_cp_read_remote_ext_features *cp;
1343 struct hci_conn *conn;
1344
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001345 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001346
1347 if (!status)
1348 return;
1349
1350 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1351 if (!cp)
1352 return;
1353
1354 hci_dev_lock(hdev);
1355
1356 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1357 if (conn) {
1358 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001359 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001360 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001361 }
1362 }
1363
1364 hci_dev_unlock(hdev);
1365}
1366
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001367static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1368{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001369 struct hci_cp_setup_sync_conn *cp;
1370 struct hci_conn *acl, *sco;
1371 __u16 handle;
1372
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001373 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001374
1375 if (!status)
1376 return;
1377
1378 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1379 if (!cp)
1380 return;
1381
1382 handle = __le16_to_cpu(cp->handle);
1383
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001384 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001385
1386 hci_dev_lock(hdev);
1387
1388 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001389 if (acl) {
1390 sco = acl->link;
1391 if (sco) {
1392 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001393
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001394 hci_proto_connect_cfm(sco, status);
1395 hci_conn_del(sco);
1396 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001397 }
1398
1399 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001400}
1401
1402static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1403{
1404 struct hci_cp_sniff_mode *cp;
1405 struct hci_conn *conn;
1406
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001407 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001408
1409 if (!status)
1410 return;
1411
1412 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1413 if (!cp)
1414 return;
1415
1416 hci_dev_lock(hdev);
1417
1418 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001419 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001420 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001421
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001422 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001423 hci_sco_setup(conn, status);
1424 }
1425
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001426 hci_dev_unlock(hdev);
1427}
1428
1429static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1430{
1431 struct hci_cp_exit_sniff_mode *cp;
1432 struct hci_conn *conn;
1433
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001434 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001435
1436 if (!status)
1437 return;
1438
1439 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1440 if (!cp)
1441 return;
1442
1443 hci_dev_lock(hdev);
1444
1445 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001446 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001447 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001448
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001449 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001450 hci_sco_setup(conn, status);
1451 }
1452
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001453 hci_dev_unlock(hdev);
1454}
1455
Johan Hedberg88c3df12012-02-09 14:27:38 +02001456static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1457{
1458 struct hci_cp_disconnect *cp;
1459 struct hci_conn *conn;
1460
1461 if (!status)
1462 return;
1463
1464 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1465 if (!cp)
1466 return;
1467
1468 hci_dev_lock(hdev);
1469
1470 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1471 if (conn)
1472 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001473 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001474
1475 hci_dev_unlock(hdev);
1476}
1477
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001478static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1479{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001480 struct hci_cp_create_phy_link *cp;
1481
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001482 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001483
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001484 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1485 if (!cp)
1486 return;
1487
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001488 hci_dev_lock(hdev);
1489
1490 if (status) {
1491 struct hci_conn *hcon;
1492
1493 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1494 if (hcon)
1495 hci_conn_del(hcon);
1496 } else {
1497 amp_write_remote_assoc(hdev, cp->phy_handle);
1498 }
1499
1500 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001501}
1502
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001503static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1504{
1505 struct hci_cp_accept_phy_link *cp;
1506
1507 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1508
1509 if (status)
1510 return;
1511
1512 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1513 if (!cp)
1514 return;
1515
1516 amp_write_remote_assoc(hdev, cp->phy_handle);
1517}
1518
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001519static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001520{
1521 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001522 struct discovery_state *discov = &hdev->discovery;
1523 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001524
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001525 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001526
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001527 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001528
1529 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1530 return;
1531
Andre Guedes3e13fa12013-03-27 20:04:56 -03001532 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1533 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1534
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001535 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001536 return;
1537
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001538 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001539
Andre Guedes343f9352012-02-17 20:39:37 -03001540 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001541 goto unlock;
1542
1543 if (list_empty(&discov->resolve)) {
1544 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1545 goto unlock;
1546 }
1547
1548 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1549 if (e && hci_resolve_name(hdev, e) == 0) {
1550 e->name_state = NAME_PENDING;
1551 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1552 } else {
1553 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1554 }
1555
1556unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001557 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001558}
1559
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001560static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001562 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001563 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564 int num_rsp = *((__u8 *) skb->data);
1565
1566 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1567
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001568 if (!num_rsp)
1569 return;
1570
Andre Guedes1519cc12012-03-21 00:03:38 -03001571 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1572 return;
1573
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001575
Johan Hedberge17acd42011-03-30 23:57:16 +03001576 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001577 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001578
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579 bacpy(&data.bdaddr, &info->bdaddr);
1580 data.pscan_rep_mode = info->pscan_rep_mode;
1581 data.pscan_period_mode = info->pscan_period_mode;
1582 data.pscan_mode = info->pscan_mode;
1583 memcpy(data.dev_class, info->dev_class, 3);
1584 data.clock_offset = info->clock_offset;
1585 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001586 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001587
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001588 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001589 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001590 info->dev_class, 0, !name_known, ssp, NULL,
1591 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001593
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594 hci_dev_unlock(hdev);
1595}
1596
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001597static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001599 struct hci_ev_conn_complete *ev = (void *) skb->data;
1600 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001602 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001603
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001605
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001606 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001607 if (!conn) {
1608 if (ev->link_type != SCO_LINK)
1609 goto unlock;
1610
1611 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1612 if (!conn)
1613 goto unlock;
1614
1615 conn->type = SCO_LINK;
1616 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001617
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001618 if (!ev->status) {
1619 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001620
1621 if (conn->type == ACL_LINK) {
1622 conn->state = BT_CONFIG;
1623 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001624
1625 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1626 !hci_find_link_key(hdev, &ev->bdaddr))
1627 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1628 else
1629 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001630 } else
1631 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001632
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001633 hci_conn_add_sysfs(conn);
1634
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001635 if (test_bit(HCI_AUTH, &hdev->flags))
1636 conn->link_mode |= HCI_LM_AUTH;
1637
1638 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1639 conn->link_mode |= HCI_LM_ENCRYPT;
1640
1641 /* Get remote features */
1642 if (conn->type == ACL_LINK) {
1643 struct hci_cp_read_remote_features cp;
1644 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001645 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001646 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001647 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001648
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001649 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001650 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001651 struct hci_cp_change_conn_ptype cp;
1652 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001653 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001654 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1655 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001656 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001657 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001658 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001659 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001660 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001661 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001662 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001663
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001664 if (conn->type == ACL_LINK)
1665 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001666
Marcel Holtmann769be972008-07-14 20:13:49 +02001667 if (ev->status) {
1668 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001669 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001670 } else if (ev->link_type != ACL_LINK)
1671 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001672
1673unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001675
1676 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677}
1678
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001679static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001681 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682 int mask = hdev->link_mode;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001683 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001685 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001686 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001688 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1689 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690
Szymon Janc138d22e2011-02-17 16:44:23 +01001691 if ((mask & HCI_LM_ACCEPT) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001692 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001694 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696
1697 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001698
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001699 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1700 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001701 memcpy(ie->data.dev_class, ev->dev_class, 3);
1702
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001703 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1704 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001706 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1707 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001708 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 hci_dev_unlock(hdev);
1710 return;
1711 }
1712 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001713
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001715
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 hci_dev_unlock(hdev);
1717
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001718 if (ev->link_type == ACL_LINK ||
1719 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001720 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001721 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001723 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001725 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1726 cp.role = 0x00; /* Become master */
1727 else
1728 cp.role = 0x01; /* Remain slave */
1729
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001730 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1731 &cp);
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001732 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001733 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001734 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001735
1736 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001737 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001738
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001739 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1740 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1741 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001742 cp.content_format = cpu_to_le16(hdev->voice_setting);
1743 cp.retrans_effort = 0xff;
1744
1745 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001746 sizeof(cp), &cp);
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001747 } else {
1748 conn->state = BT_CONNECT2;
1749 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001750 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751 } else {
1752 /* Connection rejected */
1753 struct hci_cp_reject_conn_req cp;
1754
1755 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001756 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001757 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758 }
1759}
1760
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001761static u8 hci_to_mgmt_reason(u8 err)
1762{
1763 switch (err) {
1764 case HCI_ERROR_CONNECTION_TIMEOUT:
1765 return MGMT_DEV_DISCONN_TIMEOUT;
1766 case HCI_ERROR_REMOTE_USER_TERM:
1767 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1768 case HCI_ERROR_REMOTE_POWER_OFF:
1769 return MGMT_DEV_DISCONN_REMOTE;
1770 case HCI_ERROR_LOCAL_HOST_TERM:
1771 return MGMT_DEV_DISCONN_LOCAL_HOST;
1772 default:
1773 return MGMT_DEV_DISCONN_UNKNOWN;
1774 }
1775}
1776
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001777static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001779 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001780 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001782 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784 hci_dev_lock(hdev);
1785
Marcel Holtmann04837f62006-07-03 10:02:33 +02001786 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001787 if (!conn)
1788 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001789
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001790 if (ev->status == 0)
1791 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792
Johan Hedbergb644ba32012-01-17 21:48:47 +02001793 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001794 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001795 if (ev->status) {
Johan Hedberg88c3df12012-02-09 14:27:38 +02001796 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001797 conn->dst_type, ev->status);
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001798 } else {
1799 u8 reason = hci_to_mgmt_reason(ev->reason);
1800
Johan Hedbergafc747a2012-01-15 18:11:07 +02001801 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001802 conn->dst_type, reason);
1803 }
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001804 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001805
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001806 if (ev->status == 0) {
Johan Hedberg22102462013-10-05 12:01:06 +02001807 u8 type = conn->type;
1808
1809 if (type == ACL_LINK && conn->flush_key)
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301810 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001811 hci_proto_disconn_cfm(conn, ev->reason);
1812 hci_conn_del(conn);
Johan Hedberg22102462013-10-05 12:01:06 +02001813
1814 /* Re-enable advertising if necessary, since it might
1815 * have been disabled by the connection. From the
1816 * HCI_LE_Set_Advertise_Enable command description in
1817 * the core specification (v4.0):
1818 * "The Controller shall continue advertising until the Host
1819 * issues an LE_Set_Advertise_Enable command with
1820 * Advertising_Enable set to 0x00 (Advertising is disabled)
1821 * or until a connection is created or until the Advertising
1822 * is timed out due to Directed Advertising."
1823 */
1824 if (type == LE_LINK)
Marcel Holtmann5976e602013-10-06 04:08:14 -07001825 mgmt_reenable_advertising(hdev);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001826 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001827
1828unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 hci_dev_unlock(hdev);
1830}
1831
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001832static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001833{
1834 struct hci_ev_auth_complete *ev = (void *) skb->data;
1835 struct hci_conn *conn;
1836
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001837 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001838
1839 hci_dev_lock(hdev);
1840
1841 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001842 if (!conn)
1843 goto unlock;
1844
1845 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001846 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001847 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001848 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001849 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001850 conn->link_mode |= HCI_LM_AUTH;
1851 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001852 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001853 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001854 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001855 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001856 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001857
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001858 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1859 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001860
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001861 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001862 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001863 struct hci_cp_set_conn_encrypt cp;
1864 cp.handle = ev->handle;
1865 cp.encrypt = 0x01;
1866 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001867 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001868 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001869 conn->state = BT_CONNECTED;
1870 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001871 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001872 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001873 } else {
1874 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001875
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001876 hci_conn_hold(conn);
1877 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001878 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001879 }
1880
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001881 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001882 if (!ev->status) {
1883 struct hci_cp_set_conn_encrypt cp;
1884 cp.handle = ev->handle;
1885 cp.encrypt = 0x01;
1886 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001887 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001888 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001889 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001890 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001891 }
1892 }
1893
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001894unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001895 hci_dev_unlock(hdev);
1896}
1897
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001898static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001899{
Johan Hedberg127178d2010-11-18 22:22:29 +02001900 struct hci_ev_remote_name *ev = (void *) skb->data;
1901 struct hci_conn *conn;
1902
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001903 BT_DBG("%s", hdev->name);
1904
1905 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001906
1907 hci_dev_lock(hdev);
1908
1909 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001910
1911 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1912 goto check_auth;
1913
1914 if (ev->status == 0)
1915 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001916 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001917 else
1918 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1919
1920check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001921 if (!conn)
1922 goto unlock;
1923
1924 if (!hci_outgoing_auth_needed(hdev, conn))
1925 goto unlock;
1926
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001927 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001928 struct hci_cp_auth_requested cp;
1929 cp.handle = __cpu_to_le16(conn->handle);
1930 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1931 }
1932
Johan Hedberg79c6c702011-04-28 11:28:55 -07001933unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001934 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001935}
1936
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001937static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001938{
1939 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1940 struct hci_conn *conn;
1941
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001942 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001943
1944 hci_dev_lock(hdev);
1945
1946 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1947 if (conn) {
1948 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001949 if (ev->encrypt) {
1950 /* Encryption implies authentication */
1951 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001952 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001953 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001954 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001955 conn->link_mode &= ~HCI_LM_ENCRYPT;
1956 }
1957
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001958 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001959
Gustavo Padovana7d77232012-05-13 03:20:07 -03001960 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03001961 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02001962 hci_conn_drop(conn);
Gustavo Padovana7d77232012-05-13 03:20:07 -03001963 goto unlock;
1964 }
1965
Marcel Holtmannf8558552008-07-14 20:13:49 +02001966 if (conn->state == BT_CONFIG) {
1967 if (!ev->status)
1968 conn->state = BT_CONNECTED;
1969
1970 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001971 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001972 } else
1973 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001974 }
1975
Gustavo Padovana7d77232012-05-13 03:20:07 -03001976unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001977 hci_dev_unlock(hdev);
1978}
1979
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001980static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
1981 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001982{
1983 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1984 struct hci_conn *conn;
1985
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001986 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001987
1988 hci_dev_lock(hdev);
1989
1990 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1991 if (conn) {
1992 if (!ev->status)
1993 conn->link_mode |= HCI_LM_SECURE;
1994
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001995 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001996
1997 hci_key_change_cfm(conn, ev->status);
1998 }
1999
2000 hci_dev_unlock(hdev);
2001}
2002
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002003static void hci_remote_features_evt(struct hci_dev *hdev,
2004 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002005{
2006 struct hci_ev_remote_features *ev = (void *) skb->data;
2007 struct hci_conn *conn;
2008
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002009 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002010
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002011 hci_dev_lock(hdev);
2012
2013 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002014 if (!conn)
2015 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002016
Johan Hedbergccd556f2010-11-10 17:11:51 +02002017 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002018 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002019
2020 if (conn->state != BT_CONFIG)
2021 goto unlock;
2022
2023 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2024 struct hci_cp_read_remote_ext_features cp;
2025 cp.handle = ev->handle;
2026 cp.page = 0x01;
2027 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002028 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002029 goto unlock;
2030 }
2031
Johan Hedberg671267b2012-05-12 16:11:50 -03002032 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002033 struct hci_cp_remote_name_req cp;
2034 memset(&cp, 0, sizeof(cp));
2035 bacpy(&cp.bdaddr, &conn->dst);
2036 cp.pscan_rep_mode = 0x02;
2037 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002038 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2039 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002040 conn->dst_type, 0, NULL, 0,
2041 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002042
Johan Hedberg127178d2010-11-18 22:22:29 +02002043 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002044 conn->state = BT_CONNECTED;
2045 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002046 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002047 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002048
Johan Hedbergccd556f2010-11-10 17:11:51 +02002049unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002050 hci_dev_unlock(hdev);
2051}
2052
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002053static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002054{
2055 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002056 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002057 __u16 opcode;
2058
2059 skb_pull(skb, sizeof(*ev));
2060
2061 opcode = __le16_to_cpu(ev->opcode);
2062
2063 switch (opcode) {
2064 case HCI_OP_INQUIRY_CANCEL:
2065 hci_cc_inquiry_cancel(hdev, skb);
2066 break;
2067
Andre Guedes4d934832012-03-21 00:03:35 -03002068 case HCI_OP_PERIODIC_INQ:
2069 hci_cc_periodic_inq(hdev, skb);
2070 break;
2071
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002072 case HCI_OP_EXIT_PERIODIC_INQ:
2073 hci_cc_exit_periodic_inq(hdev, skb);
2074 break;
2075
2076 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2077 hci_cc_remote_name_req_cancel(hdev, skb);
2078 break;
2079
2080 case HCI_OP_ROLE_DISCOVERY:
2081 hci_cc_role_discovery(hdev, skb);
2082 break;
2083
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002084 case HCI_OP_READ_LINK_POLICY:
2085 hci_cc_read_link_policy(hdev, skb);
2086 break;
2087
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002088 case HCI_OP_WRITE_LINK_POLICY:
2089 hci_cc_write_link_policy(hdev, skb);
2090 break;
2091
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002092 case HCI_OP_READ_DEF_LINK_POLICY:
2093 hci_cc_read_def_link_policy(hdev, skb);
2094 break;
2095
2096 case HCI_OP_WRITE_DEF_LINK_POLICY:
2097 hci_cc_write_def_link_policy(hdev, skb);
2098 break;
2099
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002100 case HCI_OP_RESET:
2101 hci_cc_reset(hdev, skb);
2102 break;
2103
2104 case HCI_OP_WRITE_LOCAL_NAME:
2105 hci_cc_write_local_name(hdev, skb);
2106 break;
2107
2108 case HCI_OP_READ_LOCAL_NAME:
2109 hci_cc_read_local_name(hdev, skb);
2110 break;
2111
2112 case HCI_OP_WRITE_AUTH_ENABLE:
2113 hci_cc_write_auth_enable(hdev, skb);
2114 break;
2115
2116 case HCI_OP_WRITE_ENCRYPT_MODE:
2117 hci_cc_write_encrypt_mode(hdev, skb);
2118 break;
2119
2120 case HCI_OP_WRITE_SCAN_ENABLE:
2121 hci_cc_write_scan_enable(hdev, skb);
2122 break;
2123
2124 case HCI_OP_READ_CLASS_OF_DEV:
2125 hci_cc_read_class_of_dev(hdev, skb);
2126 break;
2127
2128 case HCI_OP_WRITE_CLASS_OF_DEV:
2129 hci_cc_write_class_of_dev(hdev, skb);
2130 break;
2131
2132 case HCI_OP_READ_VOICE_SETTING:
2133 hci_cc_read_voice_setting(hdev, skb);
2134 break;
2135
2136 case HCI_OP_WRITE_VOICE_SETTING:
2137 hci_cc_write_voice_setting(hdev, skb);
2138 break;
2139
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002140 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2141 hci_cc_read_num_supported_iac(hdev, skb);
2142 break;
2143
Marcel Holtmann333140b2008-07-14 20:13:48 +02002144 case HCI_OP_WRITE_SSP_MODE:
2145 hci_cc_write_ssp_mode(hdev, skb);
2146 break;
2147
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002148 case HCI_OP_READ_LOCAL_VERSION:
2149 hci_cc_read_local_version(hdev, skb);
2150 break;
2151
2152 case HCI_OP_READ_LOCAL_COMMANDS:
2153 hci_cc_read_local_commands(hdev, skb);
2154 break;
2155
2156 case HCI_OP_READ_LOCAL_FEATURES:
2157 hci_cc_read_local_features(hdev, skb);
2158 break;
2159
Andre Guedes971e3a42011-06-30 19:20:52 -03002160 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2161 hci_cc_read_local_ext_features(hdev, skb);
2162 break;
2163
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002164 case HCI_OP_READ_BUFFER_SIZE:
2165 hci_cc_read_buffer_size(hdev, skb);
2166 break;
2167
2168 case HCI_OP_READ_BD_ADDR:
2169 hci_cc_read_bd_addr(hdev, skb);
2170 break;
2171
Johan Hedbergf332ec62013-03-15 17:07:11 -05002172 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2173 hci_cc_read_page_scan_activity(hdev, skb);
2174 break;
2175
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002176 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2177 hci_cc_write_page_scan_activity(hdev, skb);
2178 break;
2179
Johan Hedbergf332ec62013-03-15 17:07:11 -05002180 case HCI_OP_READ_PAGE_SCAN_TYPE:
2181 hci_cc_read_page_scan_type(hdev, skb);
2182 break;
2183
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002184 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2185 hci_cc_write_page_scan_type(hdev, skb);
2186 break;
2187
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002188 case HCI_OP_READ_DATA_BLOCK_SIZE:
2189 hci_cc_read_data_block_size(hdev, skb);
2190 break;
2191
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002192 case HCI_OP_READ_FLOW_CONTROL_MODE:
2193 hci_cc_read_flow_control_mode(hdev, skb);
2194 break;
2195
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002196 case HCI_OP_READ_LOCAL_AMP_INFO:
2197 hci_cc_read_local_amp_info(hdev, skb);
2198 break;
2199
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002200 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2201 hci_cc_read_local_amp_assoc(hdev, skb);
2202 break;
2203
Johan Hedbergd5859e22011-01-25 01:19:58 +02002204 case HCI_OP_READ_INQ_RSP_TX_POWER:
2205 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2206 break;
2207
Johan Hedberg980e1a52011-01-22 06:10:07 +02002208 case HCI_OP_PIN_CODE_REPLY:
2209 hci_cc_pin_code_reply(hdev, skb);
2210 break;
2211
2212 case HCI_OP_PIN_CODE_NEG_REPLY:
2213 hci_cc_pin_code_neg_reply(hdev, skb);
2214 break;
2215
Szymon Jancc35938b2011-03-22 13:12:21 +01002216 case HCI_OP_READ_LOCAL_OOB_DATA:
2217 hci_cc_read_local_oob_data_reply(hdev, skb);
2218 break;
2219
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002220 case HCI_OP_LE_READ_BUFFER_SIZE:
2221 hci_cc_le_read_buffer_size(hdev, skb);
2222 break;
2223
Johan Hedberg60e77322013-01-22 14:01:59 +02002224 case HCI_OP_LE_READ_LOCAL_FEATURES:
2225 hci_cc_le_read_local_features(hdev, skb);
2226 break;
2227
Johan Hedberg8fa19092012-10-19 20:57:49 +03002228 case HCI_OP_LE_READ_ADV_TX_POWER:
2229 hci_cc_le_read_adv_tx_power(hdev, skb);
2230 break;
2231
Johan Hedberga5c29682011-02-19 12:05:57 -03002232 case HCI_OP_USER_CONFIRM_REPLY:
2233 hci_cc_user_confirm_reply(hdev, skb);
2234 break;
2235
2236 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2237 hci_cc_user_confirm_neg_reply(hdev, skb);
2238 break;
2239
Brian Gix1143d452011-11-23 08:28:34 -08002240 case HCI_OP_USER_PASSKEY_REPLY:
2241 hci_cc_user_passkey_reply(hdev, skb);
2242 break;
2243
2244 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2245 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002246 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002247
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002248 case HCI_OP_LE_SET_ADV_ENABLE:
2249 hci_cc_le_set_adv_enable(hdev, skb);
2250 break;
2251
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002252 case HCI_OP_LE_SET_SCAN_ENABLE:
2253 hci_cc_le_set_scan_enable(hdev, skb);
2254 break;
2255
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002256 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2257 hci_cc_le_read_white_list_size(hdev, skb);
2258 break;
2259
Johan Hedberg9b008c02013-01-22 14:02:01 +02002260 case HCI_OP_LE_READ_SUPPORTED_STATES:
2261 hci_cc_le_read_supported_states(hdev, skb);
2262 break;
2263
Andre Guedesf9b49302011-06-30 19:20:53 -03002264 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2265 hci_cc_write_le_host_supported(hdev, skb);
2266 break;
2267
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002268 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2269 hci_cc_write_remote_amp_assoc(hdev, skb);
2270 break;
2271
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002272 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002273 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002274 break;
2275 }
2276
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002277 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002278 del_timer(&hdev->cmd_timer);
2279
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002280 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002281
Szymon Jancdbccd792012-12-11 08:51:19 +01002282 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002283 atomic_set(&hdev->cmd_cnt, 1);
2284 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002285 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002286 }
2287}
2288
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002289static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002290{
2291 struct hci_ev_cmd_status *ev = (void *) skb->data;
2292 __u16 opcode;
2293
2294 skb_pull(skb, sizeof(*ev));
2295
2296 opcode = __le16_to_cpu(ev->opcode);
2297
2298 switch (opcode) {
2299 case HCI_OP_INQUIRY:
2300 hci_cs_inquiry(hdev, ev->status);
2301 break;
2302
2303 case HCI_OP_CREATE_CONN:
2304 hci_cs_create_conn(hdev, ev->status);
2305 break;
2306
2307 case HCI_OP_ADD_SCO:
2308 hci_cs_add_sco(hdev, ev->status);
2309 break;
2310
Marcel Holtmannf8558552008-07-14 20:13:49 +02002311 case HCI_OP_AUTH_REQUESTED:
2312 hci_cs_auth_requested(hdev, ev->status);
2313 break;
2314
2315 case HCI_OP_SET_CONN_ENCRYPT:
2316 hci_cs_set_conn_encrypt(hdev, ev->status);
2317 break;
2318
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002319 case HCI_OP_REMOTE_NAME_REQ:
2320 hci_cs_remote_name_req(hdev, ev->status);
2321 break;
2322
Marcel Holtmann769be972008-07-14 20:13:49 +02002323 case HCI_OP_READ_REMOTE_FEATURES:
2324 hci_cs_read_remote_features(hdev, ev->status);
2325 break;
2326
2327 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2328 hci_cs_read_remote_ext_features(hdev, ev->status);
2329 break;
2330
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002331 case HCI_OP_SETUP_SYNC_CONN:
2332 hci_cs_setup_sync_conn(hdev, ev->status);
2333 break;
2334
2335 case HCI_OP_SNIFF_MODE:
2336 hci_cs_sniff_mode(hdev, ev->status);
2337 break;
2338
2339 case HCI_OP_EXIT_SNIFF_MODE:
2340 hci_cs_exit_sniff_mode(hdev, ev->status);
2341 break;
2342
Johan Hedberg8962ee72011-01-20 12:40:27 +02002343 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002344 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002345 break;
2346
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002347 case HCI_OP_CREATE_PHY_LINK:
2348 hci_cs_create_phylink(hdev, ev->status);
2349 break;
2350
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002351 case HCI_OP_ACCEPT_PHY_LINK:
2352 hci_cs_accept_phylink(hdev, ev->status);
2353 break;
2354
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002355 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002356 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002357 break;
2358 }
2359
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002360 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002361 del_timer(&hdev->cmd_timer);
2362
Johan Hedberg02350a72013-04-03 21:50:29 +03002363 if (ev->status ||
2364 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2365 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002366
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002367 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002368 atomic_set(&hdev->cmd_cnt, 1);
2369 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002370 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002371 }
2372}
2373
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002374static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002375{
2376 struct hci_ev_role_change *ev = (void *) skb->data;
2377 struct hci_conn *conn;
2378
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002379 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002380
2381 hci_dev_lock(hdev);
2382
2383 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2384 if (conn) {
2385 if (!ev->status) {
2386 if (ev->role)
2387 conn->link_mode &= ~HCI_LM_MASTER;
2388 else
2389 conn->link_mode |= HCI_LM_MASTER;
2390 }
2391
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002392 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002393
2394 hci_role_switch_cfm(conn, ev->status, ev->role);
2395 }
2396
2397 hci_dev_unlock(hdev);
2398}
2399
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002400static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002402 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002403 int i;
2404
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002405 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2406 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2407 return;
2408 }
2409
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002410 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002411 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002412 BT_DBG("%s bad parameters", hdev->name);
2413 return;
2414 }
2415
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002416 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2417
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002418 for (i = 0; i < ev->num_hndl; i++) {
2419 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002420 struct hci_conn *conn;
2421 __u16 handle, count;
2422
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002423 handle = __le16_to_cpu(info->handle);
2424 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002425
2426 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002427 if (!conn)
2428 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002429
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002430 conn->sent -= count;
2431
2432 switch (conn->type) {
2433 case ACL_LINK:
2434 hdev->acl_cnt += count;
2435 if (hdev->acl_cnt > hdev->acl_pkts)
2436 hdev->acl_cnt = hdev->acl_pkts;
2437 break;
2438
2439 case LE_LINK:
2440 if (hdev->le_pkts) {
2441 hdev->le_cnt += count;
2442 if (hdev->le_cnt > hdev->le_pkts)
2443 hdev->le_cnt = hdev->le_pkts;
2444 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002445 hdev->acl_cnt += count;
2446 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002447 hdev->acl_cnt = hdev->acl_pkts;
2448 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002449 break;
2450
2451 case SCO_LINK:
2452 hdev->sco_cnt += count;
2453 if (hdev->sco_cnt > hdev->sco_pkts)
2454 hdev->sco_cnt = hdev->sco_pkts;
2455 break;
2456
2457 default:
2458 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2459 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002460 }
2461 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002462
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002463 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002464}
2465
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002466static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2467 __u16 handle)
2468{
2469 struct hci_chan *chan;
2470
2471 switch (hdev->dev_type) {
2472 case HCI_BREDR:
2473 return hci_conn_hash_lookup_handle(hdev, handle);
2474 case HCI_AMP:
2475 chan = hci_chan_lookup_handle(hdev, handle);
2476 if (chan)
2477 return chan->conn;
2478 break;
2479 default:
2480 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2481 break;
2482 }
2483
2484 return NULL;
2485}
2486
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002487static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002488{
2489 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2490 int i;
2491
2492 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2493 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2494 return;
2495 }
2496
2497 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002498 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002499 BT_DBG("%s bad parameters", hdev->name);
2500 return;
2501 }
2502
2503 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002504 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002505
2506 for (i = 0; i < ev->num_hndl; i++) {
2507 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002508 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002509 __u16 handle, block_count;
2510
2511 handle = __le16_to_cpu(info->handle);
2512 block_count = __le16_to_cpu(info->blocks);
2513
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002514 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002515 if (!conn)
2516 continue;
2517
2518 conn->sent -= block_count;
2519
2520 switch (conn->type) {
2521 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002522 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002523 hdev->block_cnt += block_count;
2524 if (hdev->block_cnt > hdev->num_blocks)
2525 hdev->block_cnt = hdev->num_blocks;
2526 break;
2527
2528 default:
2529 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2530 break;
2531 }
2532 }
2533
2534 queue_work(hdev->workqueue, &hdev->tx_work);
2535}
2536
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002537static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002538{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002539 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002540 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002542 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543
2544 hci_dev_lock(hdev);
2545
Marcel Holtmann04837f62006-07-03 10:02:33 +02002546 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2547 if (conn) {
2548 conn->mode = ev->mode;
2549 conn->interval = __le16_to_cpu(ev->interval);
2550
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002551 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2552 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002553 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002554 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002555 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002556 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002557 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002558
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002559 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002560 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002561 }
2562
2563 hci_dev_unlock(hdev);
2564}
2565
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002566static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002568 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2569 struct hci_conn *conn;
2570
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002571 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002572
2573 hci_dev_lock(hdev);
2574
2575 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002576 if (!conn)
2577 goto unlock;
2578
2579 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002580 hci_conn_hold(conn);
2581 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002582 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002583 }
2584
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002585 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002586 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002587 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002588 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002589 u8 secure;
2590
2591 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2592 secure = 1;
2593 else
2594 secure = 0;
2595
Johan Hedberg744cf192011-11-08 20:40:14 +02002596 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002597 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002598
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002599unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002600 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002601}
2602
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002603static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002605 struct hci_ev_link_key_req *ev = (void *) skb->data;
2606 struct hci_cp_link_key_reply cp;
2607 struct hci_conn *conn;
2608 struct link_key *key;
2609
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002610 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002611
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002612 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002613 return;
2614
2615 hci_dev_lock(hdev);
2616
2617 key = hci_find_link_key(hdev, &ev->bdaddr);
2618 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002619 BT_DBG("%s link key not found for %pMR", hdev->name,
2620 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002621 goto not_found;
2622 }
2623
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002624 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2625 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002626
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002627 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002628 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002629 BT_DBG("%s ignoring debug key", hdev->name);
2630 goto not_found;
2631 }
2632
2633 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002634 if (conn) {
2635 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002636 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002637 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2638 goto not_found;
2639 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002640
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002641 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002642 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002643 BT_DBG("%s ignoring key unauthenticated for high security",
2644 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002645 goto not_found;
2646 }
2647
2648 conn->key_type = key->type;
2649 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002650 }
2651
2652 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002653 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002654
2655 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2656
2657 hci_dev_unlock(hdev);
2658
2659 return;
2660
2661not_found:
2662 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2663 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002664}
2665
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002666static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002668 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2669 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002670 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002671
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002672 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002673
2674 hci_dev_lock(hdev);
2675
2676 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2677 if (conn) {
2678 hci_conn_hold(conn);
2679 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002680 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002681
2682 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2683 conn->key_type = ev->key_type;
2684
David Herrmann76a68ba2013-04-06 20:28:37 +02002685 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002686 }
2687
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002688 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002689 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002690 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002691
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002692 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002693}
2694
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002695static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002696{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002697 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002698 struct hci_conn *conn;
2699
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002700 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002701
2702 hci_dev_lock(hdev);
2703
2704 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705 if (conn && !ev->status) {
2706 struct inquiry_entry *ie;
2707
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002708 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2709 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710 ie->data.clock_offset = ev->clock_offset;
2711 ie->timestamp = jiffies;
2712 }
2713 }
2714
2715 hci_dev_unlock(hdev);
2716}
2717
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002718static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002719{
2720 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2721 struct hci_conn *conn;
2722
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002723 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002724
2725 hci_dev_lock(hdev);
2726
2727 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2728 if (conn && !ev->status)
2729 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2730
2731 hci_dev_unlock(hdev);
2732}
2733
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002734static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002735{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002736 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002737 struct inquiry_entry *ie;
2738
2739 BT_DBG("%s", hdev->name);
2740
2741 hci_dev_lock(hdev);
2742
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002743 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2744 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002745 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2746 ie->timestamp = jiffies;
2747 }
2748
2749 hci_dev_unlock(hdev);
2750}
2751
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002752static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2753 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002754{
2755 struct inquiry_data data;
2756 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002757 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002758
2759 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2760
2761 if (!num_rsp)
2762 return;
2763
Andre Guedes1519cc12012-03-21 00:03:38 -03002764 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2765 return;
2766
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002767 hci_dev_lock(hdev);
2768
2769 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002770 struct inquiry_info_with_rssi_and_pscan_mode *info;
2771 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002772
Johan Hedberge17acd42011-03-30 23:57:16 +03002773 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002774 bacpy(&data.bdaddr, &info->bdaddr);
2775 data.pscan_rep_mode = info->pscan_rep_mode;
2776 data.pscan_period_mode = info->pscan_period_mode;
2777 data.pscan_mode = info->pscan_mode;
2778 memcpy(data.dev_class, info->dev_class, 3);
2779 data.clock_offset = info->clock_offset;
2780 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002781 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002782
2783 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002784 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002785 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002786 info->dev_class, info->rssi,
2787 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002788 }
2789 } else {
2790 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2791
Johan Hedberge17acd42011-03-30 23:57:16 +03002792 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002793 bacpy(&data.bdaddr, &info->bdaddr);
2794 data.pscan_rep_mode = info->pscan_rep_mode;
2795 data.pscan_period_mode = info->pscan_period_mode;
2796 data.pscan_mode = 0x00;
2797 memcpy(data.dev_class, info->dev_class, 3);
2798 data.clock_offset = info->clock_offset;
2799 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002800 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002801 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002802 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002803 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002804 info->dev_class, info->rssi,
2805 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002806 }
2807 }
2808
2809 hci_dev_unlock(hdev);
2810}
2811
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002812static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2813 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002814{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002815 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2816 struct hci_conn *conn;
2817
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002818 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002819
Marcel Holtmann41a96212008-07-14 20:13:48 +02002820 hci_dev_lock(hdev);
2821
2822 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002823 if (!conn)
2824 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002825
Johan Hedbergcad718e2013-04-17 15:00:51 +03002826 if (ev->page < HCI_MAX_PAGES)
2827 memcpy(conn->features[ev->page], ev->features, 8);
2828
Johan Hedbergccd556f2010-11-10 17:11:51 +02002829 if (!ev->status && ev->page == 0x01) {
2830 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002831
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002832 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2833 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002834 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002835
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302836 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002837 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302838 } else {
2839 /* It is mandatory by the Bluetooth specification that
2840 * Extended Inquiry Results are only used when Secure
2841 * Simple Pairing is enabled, but some devices violate
2842 * this.
2843 *
2844 * To make these devices work, the internal SSP
2845 * enabled flag needs to be cleared if the remote host
2846 * features do not indicate SSP support */
2847 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2848 }
Marcel Holtmann41a96212008-07-14 20:13:48 +02002849 }
2850
Johan Hedbergccd556f2010-11-10 17:11:51 +02002851 if (conn->state != BT_CONFIG)
2852 goto unlock;
2853
Johan Hedberg671267b2012-05-12 16:11:50 -03002854 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002855 struct hci_cp_remote_name_req cp;
2856 memset(&cp, 0, sizeof(cp));
2857 bacpy(&cp.bdaddr, &conn->dst);
2858 cp.pscan_rep_mode = 0x02;
2859 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002860 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2861 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002862 conn->dst_type, 0, NULL, 0,
2863 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002864
Johan Hedberg127178d2010-11-18 22:22:29 +02002865 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002866 conn->state = BT_CONNECTED;
2867 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002868 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002869 }
2870
2871unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002872 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002873}
2874
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002875static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2876 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002877{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002878 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2879 struct hci_conn *conn;
2880
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002881 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002882
2883 hci_dev_lock(hdev);
2884
2885 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002886 if (!conn) {
2887 if (ev->link_type == ESCO_LINK)
2888 goto unlock;
2889
2890 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2891 if (!conn)
2892 goto unlock;
2893
2894 conn->type = SCO_LINK;
2895 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002896
Marcel Holtmann732547f2009-04-19 19:14:14 +02002897 switch (ev->status) {
2898 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002899 conn->handle = __le16_to_cpu(ev->handle);
2900 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002901
2902 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002903 break;
2904
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02002905 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05002906 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002907 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002908 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002909 case 0x1f: /* Unspecified error */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002910 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02002911 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2912 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002913 if (hci_setup_sync(conn, conn->link->handle))
2914 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002915 }
2916 /* fall through */
2917
2918 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002919 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002920 break;
2921 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002922
2923 hci_proto_connect_cfm(conn, ev->status);
2924 if (ev->status)
2925 hci_conn_del(conn);
2926
2927unlock:
2928 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002929}
2930
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07002931static inline size_t eir_get_length(u8 *eir, size_t eir_len)
2932{
2933 size_t parsed = 0;
2934
2935 while (parsed < eir_len) {
2936 u8 field_len = eir[0];
2937
2938 if (field_len == 0)
2939 return parsed;
2940
2941 parsed += field_len + 1;
2942 eir += field_len + 1;
2943 }
2944
2945 return eir_len;
2946}
2947
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002948static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
2949 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002950{
2951 struct inquiry_data data;
2952 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2953 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302954 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002955
2956 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2957
2958 if (!num_rsp)
2959 return;
2960
Andre Guedes1519cc12012-03-21 00:03:38 -03002961 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2962 return;
2963
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002964 hci_dev_lock(hdev);
2965
Johan Hedberge17acd42011-03-30 23:57:16 +03002966 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002967 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002968
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002969 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002970 data.pscan_rep_mode = info->pscan_rep_mode;
2971 data.pscan_period_mode = info->pscan_period_mode;
2972 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002973 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002974 data.clock_offset = info->clock_offset;
2975 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002976 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002977
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002978 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002979 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002980 sizeof(info->data),
2981 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002982 else
2983 name_known = true;
2984
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002985 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002986 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302987 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02002988 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002989 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302990 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002991 }
2992
2993 hci_dev_unlock(hdev);
2994}
2995
Johan Hedberg1c2e0042012-06-08 23:31:13 +08002996static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
2997 struct sk_buff *skb)
2998{
2999 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3000 struct hci_conn *conn;
3001
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003002 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003003 __le16_to_cpu(ev->handle));
3004
3005 hci_dev_lock(hdev);
3006
3007 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3008 if (!conn)
3009 goto unlock;
3010
3011 if (!ev->status)
3012 conn->sec_level = conn->pending_sec_level;
3013
3014 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3015
3016 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003017 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003018 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003019 goto unlock;
3020 }
3021
3022 if (conn->state == BT_CONFIG) {
3023 if (!ev->status)
3024 conn->state = BT_CONNECTED;
3025
3026 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003027 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003028 } else {
3029 hci_auth_cfm(conn, ev->status);
3030
3031 hci_conn_hold(conn);
3032 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003033 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003034 }
3035
3036unlock:
3037 hci_dev_unlock(hdev);
3038}
3039
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003040static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003041{
3042 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003043 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3044 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003045 /* If both remote and local IO capabilities allow MITM
3046 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003047 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3048 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3049 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003050 else
Mikel Astizacabae92013-06-28 10:56:28 +02003051 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003052 }
3053
3054 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003055 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3056 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003057 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003058
3059 return conn->auth_type;
3060}
3061
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003062static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003063{
3064 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3065 struct hci_conn *conn;
3066
3067 BT_DBG("%s", hdev->name);
3068
3069 hci_dev_lock(hdev);
3070
3071 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003072 if (!conn)
3073 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003074
Johan Hedberg03b555e2011-01-04 15:40:05 +02003075 hci_conn_hold(conn);
3076
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003077 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003078 goto unlock;
3079
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003080 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003081 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003082 struct hci_cp_io_capability_reply cp;
3083
3084 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303085 /* Change the IO capability from KeyboardDisplay
3086 * to DisplayYesNo as it is not supported by BT spec. */
3087 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003088 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003089 conn->auth_type = hci_get_auth_req(conn);
3090 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003091
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003092 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3093 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003094 cp.oob_data = 0x01;
3095 else
3096 cp.oob_data = 0x00;
3097
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003098 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003099 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003100 } else {
3101 struct hci_cp_io_capability_neg_reply cp;
3102
3103 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003104 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003105
3106 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003107 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003108 }
3109
3110unlock:
3111 hci_dev_unlock(hdev);
3112}
3113
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003114static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003115{
3116 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3117 struct hci_conn *conn;
3118
3119 BT_DBG("%s", hdev->name);
3120
3121 hci_dev_lock(hdev);
3122
3123 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3124 if (!conn)
3125 goto unlock;
3126
Johan Hedberg03b555e2011-01-04 15:40:05 +02003127 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003128 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003129 if (ev->oob_data)
3130 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003131
3132unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003133 hci_dev_unlock(hdev);
3134}
3135
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003136static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3137 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003138{
3139 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003140 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003141 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003142
3143 BT_DBG("%s", hdev->name);
3144
3145 hci_dev_lock(hdev);
3146
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003147 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003148 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003149
Johan Hedberg7a828902011-04-28 11:28:53 -07003150 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3151 if (!conn)
3152 goto unlock;
3153
3154 loc_mitm = (conn->auth_type & 0x01);
3155 rem_mitm = (conn->remote_auth & 0x01);
3156
3157 /* If we require MITM but the remote device can't provide that
3158 * (it has NoInputNoOutput) then reject the confirmation
3159 * request. The only exception is when we're dedicated bonding
3160 * initiators (connect_cfm_cb set) since then we always have the MITM
3161 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003162 if (!conn->connect_cfm_cb && loc_mitm &&
3163 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003164 BT_DBG("Rejecting request: remote device can't provide MITM");
3165 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003166 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003167 goto unlock;
3168 }
3169
3170 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003171 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3172 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003173
3174 /* If we're not the initiators request authorization to
3175 * proceed from user space (mgmt_user_confirm with
3176 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003177 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003178 BT_DBG("Confirming auto-accept as acceptor");
3179 confirm_hint = 1;
3180 goto confirm;
3181 }
3182
Johan Hedberg9f616562011-04-28 11:28:54 -07003183 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003184 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003185
3186 if (hdev->auto_accept_delay > 0) {
3187 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3188 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3189 goto unlock;
3190 }
3191
Johan Hedberg7a828902011-04-28 11:28:53 -07003192 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003193 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003194 goto unlock;
3195 }
3196
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003197confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003198 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003199 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003200
3201unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003202 hci_dev_unlock(hdev);
3203}
3204
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003205static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3206 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003207{
3208 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3209
3210 BT_DBG("%s", hdev->name);
3211
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003212 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003213 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003214}
3215
Johan Hedberg92a25252012-09-06 18:39:26 +03003216static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3217 struct sk_buff *skb)
3218{
3219 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3220 struct hci_conn *conn;
3221
3222 BT_DBG("%s", hdev->name);
3223
3224 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3225 if (!conn)
3226 return;
3227
3228 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3229 conn->passkey_entered = 0;
3230
3231 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3232 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3233 conn->dst_type, conn->passkey_notify,
3234 conn->passkey_entered);
3235}
3236
3237static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3238{
3239 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3240 struct hci_conn *conn;
3241
3242 BT_DBG("%s", hdev->name);
3243
3244 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3245 if (!conn)
3246 return;
3247
3248 switch (ev->type) {
3249 case HCI_KEYPRESS_STARTED:
3250 conn->passkey_entered = 0;
3251 return;
3252
3253 case HCI_KEYPRESS_ENTERED:
3254 conn->passkey_entered++;
3255 break;
3256
3257 case HCI_KEYPRESS_ERASED:
3258 conn->passkey_entered--;
3259 break;
3260
3261 case HCI_KEYPRESS_CLEARED:
3262 conn->passkey_entered = 0;
3263 break;
3264
3265 case HCI_KEYPRESS_COMPLETED:
3266 return;
3267 }
3268
3269 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3270 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3271 conn->dst_type, conn->passkey_notify,
3272 conn->passkey_entered);
3273}
3274
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003275static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3276 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003277{
3278 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3279 struct hci_conn *conn;
3280
3281 BT_DBG("%s", hdev->name);
3282
3283 hci_dev_lock(hdev);
3284
3285 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003286 if (!conn)
3287 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003288
Johan Hedberg2a611692011-02-19 12:06:00 -03003289 /* To avoid duplicate auth_failed events to user space we check
3290 * the HCI_CONN_AUTH_PEND flag which will be set if we
3291 * initiated the authentication. A traditional auth_complete
3292 * event gets always produced as initiator and is also mapped to
3293 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003294 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003295 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003296 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003297
David Herrmann76a68ba2013-04-06 20:28:37 +02003298 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003299
3300unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003301 hci_dev_unlock(hdev);
3302}
3303
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003304static void hci_remote_host_features_evt(struct hci_dev *hdev,
3305 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003306{
3307 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3308 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003309 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003310
3311 BT_DBG("%s", hdev->name);
3312
3313 hci_dev_lock(hdev);
3314
Johan Hedbergcad718e2013-04-17 15:00:51 +03003315 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3316 if (conn)
3317 memcpy(conn->features[1], ev->features, 8);
3318
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003319 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3320 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003321 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003322
3323 hci_dev_unlock(hdev);
3324}
3325
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003326static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3327 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003328{
3329 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3330 struct oob_data *data;
3331
3332 BT_DBG("%s", hdev->name);
3333
3334 hci_dev_lock(hdev);
3335
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003336 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003337 goto unlock;
3338
Szymon Janc2763eda2011-03-22 13:12:22 +01003339 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3340 if (data) {
3341 struct hci_cp_remote_oob_data_reply cp;
3342
3343 bacpy(&cp.bdaddr, &ev->bdaddr);
3344 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3345 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3346
3347 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003348 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003349 } else {
3350 struct hci_cp_remote_oob_data_neg_reply cp;
3351
3352 bacpy(&cp.bdaddr, &ev->bdaddr);
3353 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003354 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003355 }
3356
Szymon Jance1ba1f12011-04-06 13:01:59 +02003357unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003358 hci_dev_unlock(hdev);
3359}
3360
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003361static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3362 struct sk_buff *skb)
3363{
3364 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3365 struct hci_conn *hcon, *bredr_hcon;
3366
3367 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3368 ev->status);
3369
3370 hci_dev_lock(hdev);
3371
3372 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3373 if (!hcon) {
3374 hci_dev_unlock(hdev);
3375 return;
3376 }
3377
3378 if (ev->status) {
3379 hci_conn_del(hcon);
3380 hci_dev_unlock(hdev);
3381 return;
3382 }
3383
3384 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3385
3386 hcon->state = BT_CONNECTED;
3387 bacpy(&hcon->dst, &bredr_hcon->dst);
3388
3389 hci_conn_hold(hcon);
3390 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003391 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003392
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003393 hci_conn_add_sysfs(hcon);
3394
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003395 amp_physical_cfm(bredr_hcon, hcon);
3396
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003397 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003398}
3399
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003400static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3401{
3402 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3403 struct hci_conn *hcon;
3404 struct hci_chan *hchan;
3405 struct amp_mgr *mgr;
3406
3407 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3408 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3409 ev->status);
3410
3411 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3412 if (!hcon)
3413 return;
3414
3415 /* Create AMP hchan */
3416 hchan = hci_chan_create(hcon);
3417 if (!hchan)
3418 return;
3419
3420 hchan->handle = le16_to_cpu(ev->handle);
3421
3422 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3423
3424 mgr = hcon->amp_mgr;
3425 if (mgr && mgr->bredr_chan) {
3426 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3427
3428 l2cap_chan_lock(bredr_chan);
3429
3430 bredr_chan->conn->mtu = hdev->block_mtu;
3431 l2cap_logical_cfm(bredr_chan, hchan, 0);
3432 hci_conn_hold(hcon);
3433
3434 l2cap_chan_unlock(bredr_chan);
3435 }
3436}
3437
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003438static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3439 struct sk_buff *skb)
3440{
3441 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3442 struct hci_chan *hchan;
3443
3444 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3445 le16_to_cpu(ev->handle), ev->status);
3446
3447 if (ev->status)
3448 return;
3449
3450 hci_dev_lock(hdev);
3451
3452 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3453 if (!hchan)
3454 goto unlock;
3455
3456 amp_destroy_logical_link(hchan, ev->reason);
3457
3458unlock:
3459 hci_dev_unlock(hdev);
3460}
3461
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003462static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3463 struct sk_buff *skb)
3464{
3465 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3466 struct hci_conn *hcon;
3467
3468 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3469
3470 if (ev->status)
3471 return;
3472
3473 hci_dev_lock(hdev);
3474
3475 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3476 if (hcon) {
3477 hcon->state = BT_CLOSED;
3478 hci_conn_del(hcon);
3479 }
3480
3481 hci_dev_unlock(hdev);
3482}
3483
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003484static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003485{
3486 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3487 struct hci_conn *conn;
3488
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003489 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003490
3491 hci_dev_lock(hdev);
3492
Andre Guedesb47a09b2012-07-27 15:10:15 -03003493 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003494 if (!conn) {
3495 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3496 if (!conn) {
3497 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003498 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003499 }
Andre Guedes29b79882011-05-31 14:20:54 -03003500
3501 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003502
Marcel Holtmann880be4e2013-10-13 07:25:18 -07003503 /* The advertising parameters for own address type
3504 * define which source address and source address
3505 * type this connections has.
3506 */
3507 if (bacmp(&conn->src, BDADDR_ANY)) {
3508 conn->src_type = ADDR_LE_DEV_PUBLIC;
3509 } else {
3510 bacpy(&conn->src, &hdev->static_addr);
3511 conn->src_type = ADDR_LE_DEV_RANDOM;
3512 }
3513
Andre Guedesb9b343d2012-07-27 15:10:11 -03003514 if (ev->role == LE_CONN_ROLE_MASTER) {
3515 conn->out = true;
3516 conn->link_mode |= HCI_LM_MASTER;
3517 }
Ville Tervob62f3282011-02-10 22:38:50 -03003518 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003519
Andre Guedescd17dec2012-07-27 15:10:16 -03003520 if (ev->status) {
3521 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3522 conn->dst_type, ev->status);
3523 hci_proto_connect_cfm(conn, ev->status);
3524 conn->state = BT_CLOSED;
3525 hci_conn_del(conn);
3526 goto unlock;
3527 }
3528
Johan Hedbergb644ba32012-01-17 21:48:47 +02003529 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3530 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003531 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003532
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003533 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003534 conn->handle = __le16_to_cpu(ev->handle);
3535 conn->state = BT_CONNECTED;
3536
Ville Tervofcd89c02011-02-10 22:38:47 -03003537 hci_conn_add_sysfs(conn);
3538
3539 hci_proto_connect_cfm(conn, ev->status);
3540
3541unlock:
3542 hci_dev_unlock(hdev);
3543}
3544
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003545static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003546{
Andre Guedese95beb42011-09-26 20:48:35 -03003547 u8 num_reports = skb->data[0];
3548 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003549 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003550
Andre Guedese95beb42011-09-26 20:48:35 -03003551 while (num_reports--) {
3552 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003553
Andre Guedes3c9e9192012-01-10 18:20:50 -03003554 rssi = ev->data[ev->length];
3555 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003556 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003557
Andre Guedese95beb42011-09-26 20:48:35 -03003558 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003559 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003560}
3561
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003562static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003563{
3564 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3565 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003566 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003567 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003568 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003569
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003570 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003571
3572 hci_dev_lock(hdev);
3573
3574 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003575 if (conn == NULL)
3576 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003577
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003578 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3579 if (ltk == NULL)
3580 goto not_found;
3581
3582 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003583 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003584
3585 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03003586 conn->pending_sec_level = BT_SECURITY_HIGH;
3587 else
3588 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003589
Andre Guedes89cbb4d2013-07-31 16:25:29 -03003590 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003591
3592 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3593
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003594 if (ltk->type & HCI_SMP_STK) {
3595 list_del(&ltk->list);
3596 kfree(ltk);
3597 }
3598
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003599 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003600
3601 return;
3602
3603not_found:
3604 neg.handle = ev->handle;
3605 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3606 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003607}
3608
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003609static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003610{
3611 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3612
3613 skb_pull(skb, sizeof(*le_ev));
3614
3615 switch (le_ev->subevent) {
3616 case HCI_EV_LE_CONN_COMPLETE:
3617 hci_le_conn_complete_evt(hdev, skb);
3618 break;
3619
Andre Guedes9aa04c92011-05-26 16:23:51 -03003620 case HCI_EV_LE_ADVERTISING_REPORT:
3621 hci_le_adv_report_evt(hdev, skb);
3622 break;
3623
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003624 case HCI_EV_LE_LTK_REQ:
3625 hci_le_ltk_request_evt(hdev, skb);
3626 break;
3627
Ville Tervofcd89c02011-02-10 22:38:47 -03003628 default:
3629 break;
3630 }
3631}
3632
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003633static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3634{
3635 struct hci_ev_channel_selected *ev = (void *) skb->data;
3636 struct hci_conn *hcon;
3637
3638 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3639
3640 skb_pull(skb, sizeof(*ev));
3641
3642 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3643 if (!hcon)
3644 return;
3645
3646 amp_read_loc_assoc_final_data(hdev, hcon);
3647}
3648
Linus Torvalds1da177e2005-04-16 15:20:36 -07003649void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3650{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003651 struct hci_event_hdr *hdr = (void *) skb->data;
3652 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003653
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003654 hci_dev_lock(hdev);
3655
3656 /* Received events are (currently) only needed when a request is
3657 * ongoing so avoid unnecessary memory allocation.
3658 */
3659 if (hdev->req_status == HCI_REQ_PEND) {
3660 kfree_skb(hdev->recv_evt);
3661 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3662 }
3663
3664 hci_dev_unlock(hdev);
3665
Linus Torvalds1da177e2005-04-16 15:20:36 -07003666 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3667
Johan Hedberg02350a72013-04-03 21:50:29 +03003668 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02003669 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
3670 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03003671
3672 hci_req_cmd_complete(hdev, opcode, 0);
3673 }
3674
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003675 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003676 case HCI_EV_INQUIRY_COMPLETE:
3677 hci_inquiry_complete_evt(hdev, skb);
3678 break;
3679
3680 case HCI_EV_INQUIRY_RESULT:
3681 hci_inquiry_result_evt(hdev, skb);
3682 break;
3683
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003684 case HCI_EV_CONN_COMPLETE:
3685 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003686 break;
3687
Linus Torvalds1da177e2005-04-16 15:20:36 -07003688 case HCI_EV_CONN_REQUEST:
3689 hci_conn_request_evt(hdev, skb);
3690 break;
3691
Linus Torvalds1da177e2005-04-16 15:20:36 -07003692 case HCI_EV_DISCONN_COMPLETE:
3693 hci_disconn_complete_evt(hdev, skb);
3694 break;
3695
Linus Torvalds1da177e2005-04-16 15:20:36 -07003696 case HCI_EV_AUTH_COMPLETE:
3697 hci_auth_complete_evt(hdev, skb);
3698 break;
3699
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003700 case HCI_EV_REMOTE_NAME:
3701 hci_remote_name_evt(hdev, skb);
3702 break;
3703
Linus Torvalds1da177e2005-04-16 15:20:36 -07003704 case HCI_EV_ENCRYPT_CHANGE:
3705 hci_encrypt_change_evt(hdev, skb);
3706 break;
3707
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003708 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3709 hci_change_link_key_complete_evt(hdev, skb);
3710 break;
3711
3712 case HCI_EV_REMOTE_FEATURES:
3713 hci_remote_features_evt(hdev, skb);
3714 break;
3715
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003716 case HCI_EV_CMD_COMPLETE:
3717 hci_cmd_complete_evt(hdev, skb);
3718 break;
3719
3720 case HCI_EV_CMD_STATUS:
3721 hci_cmd_status_evt(hdev, skb);
3722 break;
3723
3724 case HCI_EV_ROLE_CHANGE:
3725 hci_role_change_evt(hdev, skb);
3726 break;
3727
3728 case HCI_EV_NUM_COMP_PKTS:
3729 hci_num_comp_pkts_evt(hdev, skb);
3730 break;
3731
3732 case HCI_EV_MODE_CHANGE:
3733 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003734 break;
3735
3736 case HCI_EV_PIN_CODE_REQ:
3737 hci_pin_code_request_evt(hdev, skb);
3738 break;
3739
3740 case HCI_EV_LINK_KEY_REQ:
3741 hci_link_key_request_evt(hdev, skb);
3742 break;
3743
3744 case HCI_EV_LINK_KEY_NOTIFY:
3745 hci_link_key_notify_evt(hdev, skb);
3746 break;
3747
3748 case HCI_EV_CLOCK_OFFSET:
3749 hci_clock_offset_evt(hdev, skb);
3750 break;
3751
Marcel Holtmanna8746412008-07-14 20:13:46 +02003752 case HCI_EV_PKT_TYPE_CHANGE:
3753 hci_pkt_type_change_evt(hdev, skb);
3754 break;
3755
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003756 case HCI_EV_PSCAN_REP_MODE:
3757 hci_pscan_rep_mode_evt(hdev, skb);
3758 break;
3759
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003760 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3761 hci_inquiry_result_with_rssi_evt(hdev, skb);
3762 break;
3763
3764 case HCI_EV_REMOTE_EXT_FEATURES:
3765 hci_remote_ext_features_evt(hdev, skb);
3766 break;
3767
3768 case HCI_EV_SYNC_CONN_COMPLETE:
3769 hci_sync_conn_complete_evt(hdev, skb);
3770 break;
3771
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003772 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3773 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003774 break;
3775
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003776 case HCI_EV_KEY_REFRESH_COMPLETE:
3777 hci_key_refresh_complete_evt(hdev, skb);
3778 break;
3779
Marcel Holtmann04936842008-07-14 20:13:48 +02003780 case HCI_EV_IO_CAPA_REQUEST:
3781 hci_io_capa_request_evt(hdev, skb);
3782 break;
3783
Johan Hedberg03b555e2011-01-04 15:40:05 +02003784 case HCI_EV_IO_CAPA_REPLY:
3785 hci_io_capa_reply_evt(hdev, skb);
3786 break;
3787
Johan Hedberga5c29682011-02-19 12:05:57 -03003788 case HCI_EV_USER_CONFIRM_REQUEST:
3789 hci_user_confirm_request_evt(hdev, skb);
3790 break;
3791
Brian Gix1143d452011-11-23 08:28:34 -08003792 case HCI_EV_USER_PASSKEY_REQUEST:
3793 hci_user_passkey_request_evt(hdev, skb);
3794 break;
3795
Johan Hedberg92a25252012-09-06 18:39:26 +03003796 case HCI_EV_USER_PASSKEY_NOTIFY:
3797 hci_user_passkey_notify_evt(hdev, skb);
3798 break;
3799
3800 case HCI_EV_KEYPRESS_NOTIFY:
3801 hci_keypress_notify_evt(hdev, skb);
3802 break;
3803
Marcel Holtmann04936842008-07-14 20:13:48 +02003804 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3805 hci_simple_pair_complete_evt(hdev, skb);
3806 break;
3807
Marcel Holtmann41a96212008-07-14 20:13:48 +02003808 case HCI_EV_REMOTE_HOST_FEATURES:
3809 hci_remote_host_features_evt(hdev, skb);
3810 break;
3811
Ville Tervofcd89c02011-02-10 22:38:47 -03003812 case HCI_EV_LE_META:
3813 hci_le_meta_evt(hdev, skb);
3814 break;
3815
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003816 case HCI_EV_CHANNEL_SELECTED:
3817 hci_chan_selected_evt(hdev, skb);
3818 break;
3819
Szymon Janc2763eda2011-03-22 13:12:22 +01003820 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3821 hci_remote_oob_data_request_evt(hdev, skb);
3822 break;
3823
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003824 case HCI_EV_PHY_LINK_COMPLETE:
3825 hci_phy_link_complete_evt(hdev, skb);
3826 break;
3827
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003828 case HCI_EV_LOGICAL_LINK_COMPLETE:
3829 hci_loglink_complete_evt(hdev, skb);
3830 break;
3831
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003832 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3833 hci_disconn_loglink_complete_evt(hdev, skb);
3834 break;
3835
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003836 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3837 hci_disconn_phylink_complete_evt(hdev, skb);
3838 break;
3839
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003840 case HCI_EV_NUM_COMP_BLOCKS:
3841 hci_num_comp_blocks_evt(hdev, skb);
3842 break;
3843
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003844 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003845 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003846 break;
3847 }
3848
3849 kfree_skb(skb);
3850 hdev->stat.evt_rx++;
3851}