blob: eb99a12948c553f6404677eb8c63101f859f39a3 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <asm/unaligned.h>
28
29#include <net/bluetooth/bluetooth.h>
30#include <net/bluetooth/hci_core.h>
Mikel Astizf0d6a0e2012-08-09 09:52:30 +020031#include <net/bluetooth/mgmt.h>
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070032
Marcel Holtmann70247282013-10-10 14:54:15 -070033#include "a2mp.h"
Marcel Holtmann7ef9fbf2013-10-10 14:54:14 -070034#include "amp.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
Linus Torvalds1da177e2005-04-16 15:20:36 -070036/* Handle HCI Event packets */
37
Marcel Holtmanna9de9242007-10-20 13:33:56 +020038static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070039{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020040 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030042 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
Andre Guedes82f47852013-04-30 15:29:34 -030044 if (status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020045 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
Andre Guedes89352e72011-11-04 14:16:53 -030047 clear_bit(HCI_INQUIRY, &hdev->flags);
Andre Guedes3e13fa12013-03-27 20:04:56 -030048 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
49 wake_up_bit(&hdev->flags, HCI_INQUIRY);
Andre Guedes89352e72011-11-04 14:16:53 -030050
Marcel Holtmanna9de9242007-10-20 13:33:56 +020051 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070052}
53
Andre Guedes4d934832012-03-21 00:03:35 -030054static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
55{
56 __u8 status = *((__u8 *) skb->data);
57
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030058 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesae854a72012-03-21 00:03:36 -030059
60 if (status)
61 return;
62
63 set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
Andre Guedes4d934832012-03-21 00:03:35 -030064}
65
Marcel Holtmanna9de9242007-10-20 13:33:56 +020066static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020068 __u8 status = *((__u8 *) skb->data);
69
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030070 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020071
72 if (status)
73 return;
74
Andre Guedesae854a72012-03-21 00:03:36 -030075 clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
76
Marcel Holtmanna9de9242007-10-20 13:33:56 +020077 hci_conn_check_pending(hdev);
78}
79
Gustavo Padovan807deac2012-05-17 00:36:24 -030080static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
81 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020082{
83 BT_DBG("%s", hdev->name);
84}
85
86static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
87{
88 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030091 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
Marcel Holtmanna9de9242007-10-20 13:33:56 +020093 if (rp->status)
94 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
Marcel Holtmanna9de9242007-10-20 13:33:56 +020096 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
Marcel Holtmanna9de9242007-10-20 13:33:56 +020098 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
99 if (conn) {
100 if (rp->role)
101 conn->link_mode &= ~HCI_LM_MASTER;
102 else
103 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200105
106 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107}
108
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200109static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
110{
111 struct hci_rp_read_link_policy *rp = (void *) skb->data;
112 struct hci_conn *conn;
113
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300114 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200115
116 if (rp->status)
117 return;
118
119 hci_dev_lock(hdev);
120
121 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
122 if (conn)
123 conn->link_policy = __le16_to_cpu(rp->policy);
124
125 hci_dev_unlock(hdev);
126}
127
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200128static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200130 struct hci_rp_write_link_policy *rp = (void *) skb->data;
131 struct hci_conn *conn;
132 void *sent;
133
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300134 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200135
136 if (rp->status)
137 return;
138
139 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
140 if (!sent)
141 return;
142
143 hci_dev_lock(hdev);
144
145 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200146 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700147 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200148
149 hci_dev_unlock(hdev);
150}
151
Gustavo Padovan807deac2012-05-17 00:36:24 -0300152static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
153 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200154{
155 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
156
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300157 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200158
159 if (rp->status)
160 return;
161
162 hdev->link_policy = __le16_to_cpu(rp->policy);
163}
164
Gustavo Padovan807deac2012-05-17 00:36:24 -0300165static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
166 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200167{
168 __u8 status = *((__u8 *) skb->data);
169 void *sent;
170
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300171 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200172
173 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
174 if (!sent)
175 return;
176
177 if (!status)
178 hdev->link_policy = get_unaligned_le16(sent);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200179}
180
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200181static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
182{
183 __u8 status = *((__u8 *) skb->data);
184
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300185 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200186
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300187 clear_bit(HCI_RESET, &hdev->flags);
188
Johan Hedberga297e972012-02-21 17:55:47 +0200189 /* Reset all non-persistent flags */
Johan Hedberg2cc6fb02013-03-15 17:06:57 -0500190 hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
Andre Guedes69775ff2012-02-23 16:50:05 +0200191
192 hdev->discovery.state = DISCOVERY_STOPPED;
Johan Hedbergbbaf4442012-11-08 01:22:59 +0100193 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
194 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100195
196 memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
197 hdev->adv_data_len = 0;
Marcel Holtmannf8e808b2013-10-16 00:16:47 -0700198
199 memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
200 hdev->scan_rsp_data_len = 0;
Marcel Holtmann06f5b772013-10-19 07:09:11 -0700201
202 hdev->ssp_debug_mode = 0;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200203}
204
205static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
206{
207 __u8 status = *((__u8 *) skb->data);
208 void *sent;
209
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300210 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200211
212 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
213 if (!sent)
214 return;
215
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200216 hci_dev_lock(hdev);
217
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200218 if (test_bit(HCI_MGMT, &hdev->dev_flags))
219 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200220 else if (!status)
221 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200222
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200223 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200224}
225
226static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
227{
228 struct hci_rp_read_local_name *rp = (void *) skb->data;
229
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300230 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200231
232 if (rp->status)
233 return;
234
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200235 if (test_bit(HCI_SETUP, &hdev->dev_flags))
236 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200237}
238
239static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
240{
241 __u8 status = *((__u8 *) skb->data);
242 void *sent;
243
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300244 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200245
246 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
247 if (!sent)
248 return;
249
250 if (!status) {
251 __u8 param = *((__u8 *) sent);
252
253 if (param == AUTH_ENABLED)
254 set_bit(HCI_AUTH, &hdev->flags);
255 else
256 clear_bit(HCI_AUTH, &hdev->flags);
257 }
258
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200259 if (test_bit(HCI_MGMT, &hdev->dev_flags))
260 mgmt_auth_enable_complete(hdev, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200261}
262
263static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
264{
265 __u8 status = *((__u8 *) skb->data);
266 void *sent;
267
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300268 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200269
270 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
271 if (!sent)
272 return;
273
274 if (!status) {
275 __u8 param = *((__u8 *) sent);
276
277 if (param)
278 set_bit(HCI_ENCRYPT, &hdev->flags);
279 else
280 clear_bit(HCI_ENCRYPT, &hdev->flags);
281 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200282}
283
284static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
285{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200286 __u8 param, status = *((__u8 *) skb->data);
287 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200288 void *sent;
289
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300290 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200291
292 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
293 if (!sent)
294 return;
295
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200296 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200297
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200298 hci_dev_lock(hdev);
299
Mikel Astizfa1bd912012-08-09 09:52:29 +0200300 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200301 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200302 hdev->discov_timeout = 0;
303 goto done;
304 }
305
Johan Hedberg0663ca22013-10-02 13:43:14 +0300306 /* We need to ensure that we set this back on if someone changed
307 * the scan mode through a raw HCI socket.
308 */
309 set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
310
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200311 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
312 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200313
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200314 if (param & SCAN_INQUIRY) {
315 set_bit(HCI_ISCAN, &hdev->flags);
316 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200317 mgmt_discoverable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200318 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200319 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200320
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200321 if (param & SCAN_PAGE) {
322 set_bit(HCI_PSCAN, &hdev->flags);
323 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200324 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200325 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200326 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200327
328done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200329 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200330}
331
332static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
333{
334 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
335
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300336 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200337
338 if (rp->status)
339 return;
340
341 memcpy(hdev->dev_class, rp->dev_class, 3);
342
343 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300344 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200345}
346
347static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
348{
349 __u8 status = *((__u8 *) skb->data);
350 void *sent;
351
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300352 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200353
354 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
355 if (!sent)
356 return;
357
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100358 hci_dev_lock(hdev);
359
360 if (status == 0)
361 memcpy(hdev->dev_class, sent, 3);
362
363 if (test_bit(HCI_MGMT, &hdev->dev_flags))
364 mgmt_set_class_of_dev_complete(hdev, sent, status);
365
366 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200367}
368
369static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
370{
371 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200373
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300374 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200375
376 if (rp->status)
377 return;
378
379 setting = __le16_to_cpu(rp->voice_setting);
380
Marcel Holtmannf383f272008-07-14 20:13:47 +0200381 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200382 return;
383
384 hdev->voice_setting = setting;
385
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300386 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200387
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200388 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200390}
391
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300392static void hci_cc_write_voice_setting(struct hci_dev *hdev,
393 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200394{
395 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200396 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 void *sent;
398
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300399 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
Marcel Holtmannf383f272008-07-14 20:13:47 +0200401 if (status)
402 return;
403
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200404 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
405 if (!sent)
406 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
Marcel Holtmannf383f272008-07-14 20:13:47 +0200408 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410 if (hdev->voice_setting == setting)
411 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
Marcel Holtmannf383f272008-07-14 20:13:47 +0200413 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300415 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200416
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200417 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200418 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419}
420
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -0700421static void hci_cc_read_num_supported_iac(struct hci_dev *hdev,
422 struct sk_buff *skb)
423{
424 struct hci_rp_read_num_supported_iac *rp = (void *) skb->data;
425
426 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
427
428 if (rp->status)
429 return;
430
431 hdev->num_iac = rp->num_iac;
432
433 BT_DBG("%s num iac %d", hdev->name, hdev->num_iac);
434}
435
Marcel Holtmann333140b2008-07-14 20:13:48 +0200436static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
437{
438 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300439 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200440
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300441 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200442
Marcel Holtmann333140b2008-07-14 20:13:48 +0200443 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
444 if (!sent)
445 return;
446
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300447 if (!status) {
448 if (sent->mode)
Johan Hedbergcad718e2013-04-17 15:00:51 +0300449 hdev->features[1][0] |= LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300450 else
Johan Hedbergcad718e2013-04-17 15:00:51 +0300451 hdev->features[1][0] &= ~LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300452 }
453
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200454 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300455 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200456 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300457 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200458 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
459 else
460 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
461 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200462}
463
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200464static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
465{
466 struct hci_rp_read_local_version *rp = (void *) skb->data;
467
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300468 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200469
470 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200471 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200472
Marcel Holtmann0d5551f2013-10-18 12:04:50 -0700473 if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
474 hdev->hci_ver = rp->hci_ver;
475 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
476 hdev->lmp_ver = rp->lmp_ver;
477 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
478 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
479 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200480}
481
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300482static void hci_cc_read_local_commands(struct hci_dev *hdev,
483 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200484{
485 struct hci_rp_read_local_commands *rp = (void *) skb->data;
486
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300487 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200488
Marcel Holtmann6a070e62013-10-31 04:54:33 -0700489 if (rp->status)
490 return;
491
492 if (test_bit(HCI_SETUP, &hdev->dev_flags))
Johan Hedberg2177bab2013-03-05 20:37:43 +0200493 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200494}
495
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300496static void hci_cc_read_local_features(struct hci_dev *hdev,
497 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200498{
499 struct hci_rp_read_local_features *rp = (void *) skb->data;
500
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300501 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200502
503 if (rp->status)
504 return;
505
506 memcpy(hdev->features, rp->features, 8);
507
508 /* Adjust default settings according to features
509 * supported by device. */
510
Johan Hedbergcad718e2013-04-17 15:00:51 +0300511 if (hdev->features[0][0] & LMP_3SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200512 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
513
Johan Hedbergcad718e2013-04-17 15:00:51 +0300514 if (hdev->features[0][0] & LMP_5SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200515 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
516
Johan Hedbergcad718e2013-04-17 15:00:51 +0300517 if (hdev->features[0][1] & LMP_HV2) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200518 hdev->pkt_type |= (HCI_HV2);
519 hdev->esco_type |= (ESCO_HV2);
520 }
521
Johan Hedbergcad718e2013-04-17 15:00:51 +0300522 if (hdev->features[0][1] & LMP_HV3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200523 hdev->pkt_type |= (HCI_HV3);
524 hdev->esco_type |= (ESCO_HV3);
525 }
526
Andre Guedes45db810f2012-07-24 15:03:49 -0300527 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200528 hdev->esco_type |= (ESCO_EV3);
529
Johan Hedbergcad718e2013-04-17 15:00:51 +0300530 if (hdev->features[0][4] & LMP_EV4)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200531 hdev->esco_type |= (ESCO_EV4);
532
Johan Hedbergcad718e2013-04-17 15:00:51 +0300533 if (hdev->features[0][4] & LMP_EV5)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200534 hdev->esco_type |= (ESCO_EV5);
535
Johan Hedbergcad718e2013-04-17 15:00:51 +0300536 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100537 hdev->esco_type |= (ESCO_2EV3);
538
Johan Hedbergcad718e2013-04-17 15:00:51 +0300539 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100540 hdev->esco_type |= (ESCO_3EV3);
541
Johan Hedbergcad718e2013-04-17 15:00:51 +0300542 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100543 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200544}
545
Andre Guedes971e3a42011-06-30 19:20:52 -0300546static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300547 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300548{
549 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
550
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300551 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300552
553 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200554 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300555
Marcel Holtmann57af75a2013-10-18 12:04:47 -0700556 if (hdev->max_page < rp->max_page)
557 hdev->max_page = rp->max_page;
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300558
Johan Hedbergcad718e2013-04-17 15:00:51 +0300559 if (rp->page < HCI_MAX_PAGES)
560 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300561}
562
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200563static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300564 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200565{
566 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
567
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300568 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200569
Johan Hedberg42c6b122013-03-05 20:37:49 +0200570 if (!rp->status)
571 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200572}
573
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200574static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
575{
576 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
577
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300578 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200579
580 if (rp->status)
581 return;
582
583 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
584 hdev->sco_mtu = rp->sco_mtu;
585 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
586 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
587
588 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
589 hdev->sco_mtu = 64;
590 hdev->sco_pkts = 8;
591 }
592
593 hdev->acl_cnt = hdev->acl_pkts;
594 hdev->sco_cnt = hdev->sco_pkts;
595
Gustavo Padovan807deac2012-05-17 00:36:24 -0300596 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
597 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200598}
599
600static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
601{
602 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
603
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300604 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200605
606 if (!rp->status)
607 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200608}
609
Johan Hedbergf332ec62013-03-15 17:07:11 -0500610static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
611 struct sk_buff *skb)
612{
613 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
614
615 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
616
617 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
618 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
619 hdev->page_scan_window = __le16_to_cpu(rp->window);
620 }
621}
622
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500623static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
624 struct sk_buff *skb)
625{
626 u8 status = *((u8 *) skb->data);
627 struct hci_cp_write_page_scan_activity *sent;
628
629 BT_DBG("%s status 0x%2.2x", hdev->name, status);
630
631 if (status)
632 return;
633
634 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
635 if (!sent)
636 return;
637
638 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
639 hdev->page_scan_window = __le16_to_cpu(sent->window);
640}
641
Johan Hedbergf332ec62013-03-15 17:07:11 -0500642static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
643 struct sk_buff *skb)
644{
645 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
646
647 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
648
649 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
650 hdev->page_scan_type = rp->type;
651}
652
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500653static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
654 struct sk_buff *skb)
655{
656 u8 status = *((u8 *) skb->data);
657 u8 *type;
658
659 BT_DBG("%s status 0x%2.2x", hdev->name, status);
660
661 if (status)
662 return;
663
664 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
665 if (type)
666 hdev->page_scan_type = *type;
667}
668
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200669static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300670 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200671{
672 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
673
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300674 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200675
676 if (rp->status)
677 return;
678
679 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
680 hdev->block_len = __le16_to_cpu(rp->block_len);
681 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
682
683 hdev->block_cnt = hdev->num_blocks;
684
685 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300686 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200687}
688
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300689static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300690 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300691{
692 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
693
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300694 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300695
696 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300697 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300698
699 hdev->amp_status = rp->amp_status;
700 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
701 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
702 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
703 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
704 hdev->amp_type = rp->amp_type;
705 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
706 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
707 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
708 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
709
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300710a2mp_rsp:
711 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300712}
713
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300714static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
715 struct sk_buff *skb)
716{
717 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
718 struct amp_assoc *assoc = &hdev->loc_assoc;
719 size_t rem_len, frag_len;
720
721 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
722
723 if (rp->status)
724 goto a2mp_rsp;
725
726 frag_len = skb->len - sizeof(*rp);
727 rem_len = __le16_to_cpu(rp->rem_len);
728
729 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300730 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300731
732 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
733 assoc->offset += frag_len;
734
735 /* Read other fragments */
736 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
737
738 return;
739 }
740
741 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
742 assoc->len = assoc->offset + rem_len;
743 assoc->offset = 0;
744
745a2mp_rsp:
746 /* Send A2MP Rsp when all fragments are received */
747 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300748 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300749}
750
Johan Hedbergd5859e22011-01-25 01:19:58 +0200751static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300752 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200753{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700754 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200755
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300756 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200757
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700758 if (!rp->status)
759 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200760}
761
Johan Hedberg980e1a52011-01-22 06:10:07 +0200762static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
763{
764 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
765 struct hci_cp_pin_code_reply *cp;
766 struct hci_conn *conn;
767
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300768 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200769
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200770 hci_dev_lock(hdev);
771
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200772 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200773 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200774
Mikel Astizfa1bd912012-08-09 09:52:29 +0200775 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200776 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200777
778 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
779 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200780 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200781
782 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
783 if (conn)
784 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200785
786unlock:
787 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200788}
789
790static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
791{
792 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
793
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300794 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200795
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200796 hci_dev_lock(hdev);
797
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200798 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200799 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300800 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200801
802 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200803}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200804
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300805static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
806 struct sk_buff *skb)
807{
808 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
809
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300810 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300811
812 if (rp->status)
813 return;
814
815 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
816 hdev->le_pkts = rp->le_max_pkt;
817
818 hdev->le_cnt = hdev->le_pkts;
819
820 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300821}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200822
Johan Hedberg60e77322013-01-22 14:01:59 +0200823static void hci_cc_le_read_local_features(struct hci_dev *hdev,
824 struct sk_buff *skb)
825{
826 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
827
828 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
829
830 if (!rp->status)
831 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200832}
833
Johan Hedberg8fa19092012-10-19 20:57:49 +0300834static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
835 struct sk_buff *skb)
836{
837 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
838
839 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
840
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500841 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300842 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300843}
844
Johan Hedberga5c29682011-02-19 12:05:57 -0300845static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
846{
847 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
848
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300849 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300850
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200851 hci_dev_lock(hdev);
852
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200853 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300854 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
855 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200856
857 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300858}
859
860static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300861 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300862{
863 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
864
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300865 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300866
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200867 hci_dev_lock(hdev);
868
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200869 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200870 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300871 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200872
873 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300874}
875
Brian Gix1143d452011-11-23 08:28:34 -0800876static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
877{
878 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
879
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300880 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800881
882 hci_dev_lock(hdev);
883
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200884 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200885 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300886 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800887
888 hci_dev_unlock(hdev);
889}
890
891static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300892 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800893{
894 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
895
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300896 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800897
898 hci_dev_lock(hdev);
899
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200900 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800901 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300902 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800903
904 hci_dev_unlock(hdev);
905}
906
Szymon Jancc35938b2011-03-22 13:12:21 +0100907static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300908 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100909{
910 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
911
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300912 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100913
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200914 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +0200915 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +0100916 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200917 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100918}
919
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100920static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
921{
922 __u8 *sent, status = *((__u8 *) skb->data);
923
924 BT_DBG("%s status 0x%2.2x", hdev->name, status);
925
926 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
927 if (!sent)
928 return;
929
930 hci_dev_lock(hdev);
931
932 if (!status) {
933 if (*sent)
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200934 set_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100935 else
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200936 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100937 }
938
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500939 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100940}
941
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300942static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300943 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300944{
945 struct hci_cp_le_set_scan_enable *cp;
946 __u8 status = *((__u8 *) skb->data);
947
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300948 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300949
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300950 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
951 if (!cp)
952 return;
953
Andre Guedes3fd319b2013-04-30 15:29:36 -0300954 if (status)
955 return;
956
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200957 switch (cp->enable) {
Andre Guedes76a388be2013-04-04 20:21:02 -0300958 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300959 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200960 break;
961
Andre Guedes76a388be2013-04-04 20:21:02 -0300962 case LE_SCAN_DISABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300963 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200964 break;
965
966 default:
967 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
968 break;
Andre Guedes35815082011-05-26 16:23:53 -0300969 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300970}
971
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200972static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
973 struct sk_buff *skb)
974{
975 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
976
977 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
978
979 if (!rp->status)
980 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200981}
982
Johan Hedberg9b008c02013-01-22 14:02:01 +0200983static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
984 struct sk_buff *skb)
985{
986 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
987
988 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
989
990 if (!rp->status)
991 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +0200992}
993
Gustavo Padovan6039aa72012-05-23 04:04:18 -0300994static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
995 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -0300996{
Johan Hedberg06199cf2012-02-22 16:37:11 +0200997 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -0300998 __u8 status = *((__u8 *) skb->data);
999
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001000 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001001
Johan Hedberg06199cf2012-02-22 16:37:11 +02001002 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001003 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001004 return;
1005
Johan Hedberg8f984df2012-02-28 01:07:22 +02001006 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001007 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001008 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001009 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1010 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001011 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001012 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001013 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001014 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001015
1016 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001017 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001018 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001019 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001020 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001021}
1022
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001023static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1024 struct sk_buff *skb)
1025{
1026 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1027
1028 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1029 hdev->name, rp->status, rp->phy_handle);
1030
1031 if (rp->status)
1032 return;
1033
1034 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1035}
1036
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001037static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001038{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001039 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001040
1041 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001042 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001043 return;
1044 }
1045
Andre Guedes89352e72011-11-04 14:16:53 -03001046 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001047}
1048
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001049static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001051 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001054 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001055
1056 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 if (!cp)
1058 return;
1059
1060 hci_dev_lock(hdev);
1061
1062 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1063
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001064 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065
1066 if (status) {
1067 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001068 if (status != 0x0c || conn->attempt > 2) {
1069 conn->state = BT_CLOSED;
1070 hci_proto_connect_cfm(conn, status);
1071 hci_conn_del(conn);
1072 } else
1073 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 }
1075 } else {
1076 if (!conn) {
1077 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1078 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001079 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 conn->link_mode |= HCI_LM_MASTER;
1081 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001082 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083 }
1084 }
1085
1086 hci_dev_unlock(hdev);
1087}
1088
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001089static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001091 struct hci_cp_add_sco *cp;
1092 struct hci_conn *acl, *sco;
1093 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001095 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001096
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001097 if (!status)
1098 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001100 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1101 if (!cp)
1102 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001104 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001106 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001107
1108 hci_dev_lock(hdev);
1109
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001110 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001111 if (acl) {
1112 sco = acl->link;
1113 if (sco) {
1114 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001115
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001116 hci_proto_connect_cfm(sco, status);
1117 hci_conn_del(sco);
1118 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001119 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001120
1121 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122}
1123
Marcel Holtmannf8558552008-07-14 20:13:49 +02001124static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1125{
1126 struct hci_cp_auth_requested *cp;
1127 struct hci_conn *conn;
1128
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001129 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001130
1131 if (!status)
1132 return;
1133
1134 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1135 if (!cp)
1136 return;
1137
1138 hci_dev_lock(hdev);
1139
1140 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1141 if (conn) {
1142 if (conn->state == BT_CONFIG) {
1143 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001144 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001145 }
1146 }
1147
1148 hci_dev_unlock(hdev);
1149}
1150
1151static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1152{
1153 struct hci_cp_set_conn_encrypt *cp;
1154 struct hci_conn *conn;
1155
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001156 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001157
1158 if (!status)
1159 return;
1160
1161 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1162 if (!cp)
1163 return;
1164
1165 hci_dev_lock(hdev);
1166
1167 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1168 if (conn) {
1169 if (conn->state == BT_CONFIG) {
1170 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001171 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001172 }
1173 }
1174
1175 hci_dev_unlock(hdev);
1176}
1177
Johan Hedberg127178d2010-11-18 22:22:29 +02001178static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001179 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001180{
Johan Hedberg392599b2010-11-18 22:22:28 +02001181 if (conn->state != BT_CONFIG || !conn->out)
1182 return 0;
1183
Johan Hedberg765c2a92011-01-19 12:06:52 +05301184 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001185 return 0;
1186
1187 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001188 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001189 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1190 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001191 return 0;
1192
Johan Hedberg392599b2010-11-18 22:22:28 +02001193 return 1;
1194}
1195
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001196static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001197 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001198{
1199 struct hci_cp_remote_name_req cp;
1200
1201 memset(&cp, 0, sizeof(cp));
1202
1203 bacpy(&cp.bdaddr, &e->data.bdaddr);
1204 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1205 cp.pscan_mode = e->data.pscan_mode;
1206 cp.clock_offset = e->data.clock_offset;
1207
1208 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1209}
1210
Johan Hedbergb644ba32012-01-17 21:48:47 +02001211static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001212{
1213 struct discovery_state *discov = &hdev->discovery;
1214 struct inquiry_entry *e;
1215
Johan Hedbergb644ba32012-01-17 21:48:47 +02001216 if (list_empty(&discov->resolve))
1217 return false;
1218
1219 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001220 if (!e)
1221 return false;
1222
Johan Hedbergb644ba32012-01-17 21:48:47 +02001223 if (hci_resolve_name(hdev, e) == 0) {
1224 e->name_state = NAME_PENDING;
1225 return true;
1226 }
1227
1228 return false;
1229}
1230
1231static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001232 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001233{
1234 struct discovery_state *discov = &hdev->discovery;
1235 struct inquiry_entry *e;
1236
1237 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001238 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1239 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001240
1241 if (discov->state == DISCOVERY_STOPPED)
1242 return;
1243
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001244 if (discov->state == DISCOVERY_STOPPING)
1245 goto discov_complete;
1246
1247 if (discov->state != DISCOVERY_RESOLVING)
1248 return;
1249
1250 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001251 /* If the device was not found in a list of found devices names of which
1252 * are pending. there is no need to continue resolving a next name as it
1253 * will be done upon receiving another Remote Name Request Complete
1254 * Event */
1255 if (!e)
1256 return;
1257
1258 list_del(&e->list);
1259 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001260 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001261 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1262 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001263 } else {
1264 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001265 }
1266
Johan Hedbergb644ba32012-01-17 21:48:47 +02001267 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001268 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001269
1270discov_complete:
1271 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1272}
1273
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001274static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1275{
Johan Hedberg127178d2010-11-18 22:22:29 +02001276 struct hci_cp_remote_name_req *cp;
1277 struct hci_conn *conn;
1278
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001279 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001280
1281 /* If successful wait for the name req complete event before
1282 * checking for the need to do authentication */
1283 if (!status)
1284 return;
1285
1286 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1287 if (!cp)
1288 return;
1289
1290 hci_dev_lock(hdev);
1291
1292 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001293
1294 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1295 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1296
Johan Hedberg79c6c702011-04-28 11:28:55 -07001297 if (!conn)
1298 goto unlock;
1299
1300 if (!hci_outgoing_auth_needed(hdev, conn))
1301 goto unlock;
1302
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001303 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001304 struct hci_cp_auth_requested auth_cp;
1305
1306 auth_cp.handle = __cpu_to_le16(conn->handle);
1307 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1308 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001309 }
1310
Johan Hedberg79c6c702011-04-28 11:28:55 -07001311unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001312 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001313}
1314
Marcel Holtmann769be972008-07-14 20:13:49 +02001315static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1316{
1317 struct hci_cp_read_remote_features *cp;
1318 struct hci_conn *conn;
1319
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001320 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001321
1322 if (!status)
1323 return;
1324
1325 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1326 if (!cp)
1327 return;
1328
1329 hci_dev_lock(hdev);
1330
1331 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1332 if (conn) {
1333 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001334 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001335 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001336 }
1337 }
1338
1339 hci_dev_unlock(hdev);
1340}
1341
1342static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1343{
1344 struct hci_cp_read_remote_ext_features *cp;
1345 struct hci_conn *conn;
1346
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001347 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001348
1349 if (!status)
1350 return;
1351
1352 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1353 if (!cp)
1354 return;
1355
1356 hci_dev_lock(hdev);
1357
1358 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1359 if (conn) {
1360 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001361 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001362 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001363 }
1364 }
1365
1366 hci_dev_unlock(hdev);
1367}
1368
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001369static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1370{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001371 struct hci_cp_setup_sync_conn *cp;
1372 struct hci_conn *acl, *sco;
1373 __u16 handle;
1374
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001375 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001376
1377 if (!status)
1378 return;
1379
1380 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1381 if (!cp)
1382 return;
1383
1384 handle = __le16_to_cpu(cp->handle);
1385
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001386 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001387
1388 hci_dev_lock(hdev);
1389
1390 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001391 if (acl) {
1392 sco = acl->link;
1393 if (sco) {
1394 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001395
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001396 hci_proto_connect_cfm(sco, status);
1397 hci_conn_del(sco);
1398 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001399 }
1400
1401 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001402}
1403
1404static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1405{
1406 struct hci_cp_sniff_mode *cp;
1407 struct hci_conn *conn;
1408
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001409 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001410
1411 if (!status)
1412 return;
1413
1414 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1415 if (!cp)
1416 return;
1417
1418 hci_dev_lock(hdev);
1419
1420 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001421 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001422 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001423
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001424 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001425 hci_sco_setup(conn, status);
1426 }
1427
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001428 hci_dev_unlock(hdev);
1429}
1430
1431static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1432{
1433 struct hci_cp_exit_sniff_mode *cp;
1434 struct hci_conn *conn;
1435
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001436 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001437
1438 if (!status)
1439 return;
1440
1441 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1442 if (!cp)
1443 return;
1444
1445 hci_dev_lock(hdev);
1446
1447 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001448 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001449 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001450
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001451 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001452 hci_sco_setup(conn, status);
1453 }
1454
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001455 hci_dev_unlock(hdev);
1456}
1457
Johan Hedberg88c3df12012-02-09 14:27:38 +02001458static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1459{
1460 struct hci_cp_disconnect *cp;
1461 struct hci_conn *conn;
1462
1463 if (!status)
1464 return;
1465
1466 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1467 if (!cp)
1468 return;
1469
1470 hci_dev_lock(hdev);
1471
1472 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1473 if (conn)
1474 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001475 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001476
1477 hci_dev_unlock(hdev);
1478}
1479
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001480static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1481{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001482 struct hci_cp_create_phy_link *cp;
1483
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001484 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001485
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001486 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1487 if (!cp)
1488 return;
1489
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001490 hci_dev_lock(hdev);
1491
1492 if (status) {
1493 struct hci_conn *hcon;
1494
1495 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1496 if (hcon)
1497 hci_conn_del(hcon);
1498 } else {
1499 amp_write_remote_assoc(hdev, cp->phy_handle);
1500 }
1501
1502 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001503}
1504
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001505static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1506{
1507 struct hci_cp_accept_phy_link *cp;
1508
1509 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1510
1511 if (status)
1512 return;
1513
1514 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1515 if (!cp)
1516 return;
1517
1518 amp_write_remote_assoc(hdev, cp->phy_handle);
1519}
1520
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001521static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001522{
1523 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001524 struct discovery_state *discov = &hdev->discovery;
1525 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001526
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001527 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001528
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001529 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001530
1531 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1532 return;
1533
Andre Guedes3e13fa12013-03-27 20:04:56 -03001534 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1535 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1536
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001537 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001538 return;
1539
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001540 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001541
Andre Guedes343f9352012-02-17 20:39:37 -03001542 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001543 goto unlock;
1544
1545 if (list_empty(&discov->resolve)) {
1546 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1547 goto unlock;
1548 }
1549
1550 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1551 if (e && hci_resolve_name(hdev, e) == 0) {
1552 e->name_state = NAME_PENDING;
1553 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1554 } else {
1555 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1556 }
1557
1558unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001559 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001560}
1561
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001562static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001564 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001565 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566 int num_rsp = *((__u8 *) skb->data);
1567
1568 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1569
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001570 if (!num_rsp)
1571 return;
1572
Andre Guedes1519cc12012-03-21 00:03:38 -03001573 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1574 return;
1575
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001577
Johan Hedberge17acd42011-03-30 23:57:16 +03001578 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001579 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001580
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 bacpy(&data.bdaddr, &info->bdaddr);
1582 data.pscan_rep_mode = info->pscan_rep_mode;
1583 data.pscan_period_mode = info->pscan_period_mode;
1584 data.pscan_mode = info->pscan_mode;
1585 memcpy(data.dev_class, info->dev_class, 3);
1586 data.clock_offset = info->clock_offset;
1587 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001588 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001589
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001590 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001591 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001592 info->dev_class, 0, !name_known, ssp, NULL,
1593 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001595
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596 hci_dev_unlock(hdev);
1597}
1598
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001599static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001601 struct hci_ev_conn_complete *ev = (void *) skb->data;
1602 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001604 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001605
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001607
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001608 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001609 if (!conn) {
1610 if (ev->link_type != SCO_LINK)
1611 goto unlock;
1612
1613 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1614 if (!conn)
1615 goto unlock;
1616
1617 conn->type = SCO_LINK;
1618 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001619
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001620 if (!ev->status) {
1621 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001622
1623 if (conn->type == ACL_LINK) {
1624 conn->state = BT_CONFIG;
1625 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001626
1627 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1628 !hci_find_link_key(hdev, &ev->bdaddr))
1629 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1630 else
1631 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001632 } else
1633 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001634
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001635 hci_conn_add_sysfs(conn);
1636
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001637 if (test_bit(HCI_AUTH, &hdev->flags))
1638 conn->link_mode |= HCI_LM_AUTH;
1639
1640 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1641 conn->link_mode |= HCI_LM_ENCRYPT;
1642
1643 /* Get remote features */
1644 if (conn->type == ACL_LINK) {
1645 struct hci_cp_read_remote_features cp;
1646 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001647 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001648 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001649 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001650
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001651 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001652 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001653 struct hci_cp_change_conn_ptype cp;
1654 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001655 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001656 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1657 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001658 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001659 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001660 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001661 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001662 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001663 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001664 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001665
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001666 if (conn->type == ACL_LINK)
1667 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001668
Marcel Holtmann769be972008-07-14 20:13:49 +02001669 if (ev->status) {
1670 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001671 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001672 } else if (ev->link_type != ACL_LINK)
1673 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001674
1675unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001677
1678 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679}
1680
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001681static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001683 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 int mask = hdev->link_mode;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001685 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001687 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001688 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001690 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1691 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692
Szymon Janc138d22e2011-02-17 16:44:23 +01001693 if ((mask & HCI_LM_ACCEPT) &&
Marcel Holtmannb9ee0a72013-10-17 17:24:13 -07001694 !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001696 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698
1699 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001700
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001701 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1702 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001703 memcpy(ie->data.dev_class, ev->dev_class, 3);
1704
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001705 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1706 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001708 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1709 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001710 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 hci_dev_unlock(hdev);
1712 return;
1713 }
1714 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001715
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001717
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 hci_dev_unlock(hdev);
1719
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001720 if (ev->link_type == ACL_LINK ||
1721 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001722 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001723 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001725 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001727 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1728 cp.role = 0x00; /* Become master */
1729 else
1730 cp.role = 0x01; /* Remain slave */
1731
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001732 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1733 &cp);
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001734 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001735 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001736 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001737
1738 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001739 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001740
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001741 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1742 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1743 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001744 cp.content_format = cpu_to_le16(hdev->voice_setting);
1745 cp.retrans_effort = 0xff;
1746
1747 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001748 sizeof(cp), &cp);
Frédéric Dalleau20714bfe2012-11-21 10:51:12 +01001749 } else {
1750 conn->state = BT_CONNECT2;
1751 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001752 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 } else {
1754 /* Connection rejected */
1755 struct hci_cp_reject_conn_req cp;
1756
1757 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001758 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001759 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 }
1761}
1762
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001763static u8 hci_to_mgmt_reason(u8 err)
1764{
1765 switch (err) {
1766 case HCI_ERROR_CONNECTION_TIMEOUT:
1767 return MGMT_DEV_DISCONN_TIMEOUT;
1768 case HCI_ERROR_REMOTE_USER_TERM:
1769 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1770 case HCI_ERROR_REMOTE_POWER_OFF:
1771 return MGMT_DEV_DISCONN_REMOTE;
1772 case HCI_ERROR_LOCAL_HOST_TERM:
1773 return MGMT_DEV_DISCONN_LOCAL_HOST;
1774 default:
1775 return MGMT_DEV_DISCONN_UNKNOWN;
1776 }
1777}
1778
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001779static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001781 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Andre Guedesabf54a52013-11-07 17:36:09 -03001782 u8 reason = hci_to_mgmt_reason(ev->reason);
Marcel Holtmann04837f62006-07-03 10:02:33 +02001783 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001785 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 hci_dev_lock(hdev);
1788
Marcel Holtmann04837f62006-07-03 10:02:33 +02001789 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001790 if (!conn)
1791 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001792
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001793 if (ev->status == 0)
1794 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795
Andre Guedesabf54a52013-11-07 17:36:09 -03001796 if (ev->status) {
1797 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1798 conn->dst_type, ev->status);
1799 goto unlock;
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001800 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001801
Andre Guedesabf54a52013-11-07 17:36:09 -03001802 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1803 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
1804 conn->dst_type, reason);
1805
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;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002549
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002550 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2551 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002552 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002553 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002554 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002555 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002556 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002557
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002558 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002559 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002560 }
2561
2562 hci_dev_unlock(hdev);
2563}
2564
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002565static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002567 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2568 struct hci_conn *conn;
2569
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002570 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002571
2572 hci_dev_lock(hdev);
2573
2574 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002575 if (!conn)
2576 goto unlock;
2577
2578 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002579 hci_conn_hold(conn);
2580 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002581 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002582 }
2583
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002584 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002585 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002586 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002587 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002588 u8 secure;
2589
2590 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2591 secure = 1;
2592 else
2593 secure = 0;
2594
Johan Hedberg744cf192011-11-08 20:40:14 +02002595 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002596 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002597
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002598unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002599 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600}
2601
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002602static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002603{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002604 struct hci_ev_link_key_req *ev = (void *) skb->data;
2605 struct hci_cp_link_key_reply cp;
2606 struct hci_conn *conn;
2607 struct link_key *key;
2608
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002609 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002610
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002611 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002612 return;
2613
2614 hci_dev_lock(hdev);
2615
2616 key = hci_find_link_key(hdev, &ev->bdaddr);
2617 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002618 BT_DBG("%s link key not found for %pMR", hdev->name,
2619 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002620 goto not_found;
2621 }
2622
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002623 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2624 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002625
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002626 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002627 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002628 BT_DBG("%s ignoring debug key", hdev->name);
2629 goto not_found;
2630 }
2631
2632 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002633 if (conn) {
2634 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002635 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002636 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2637 goto not_found;
2638 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002639
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002640 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002641 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002642 BT_DBG("%s ignoring key unauthenticated for high security",
2643 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002644 goto not_found;
2645 }
2646
2647 conn->key_type = key->type;
2648 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002649 }
2650
2651 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002652 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002653
2654 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2655
2656 hci_dev_unlock(hdev);
2657
2658 return;
2659
2660not_found:
2661 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2662 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663}
2664
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002665static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002667 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2668 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002669 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002670
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002671 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002672
2673 hci_dev_lock(hdev);
2674
2675 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2676 if (conn) {
2677 hci_conn_hold(conn);
2678 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002679 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002680
2681 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2682 conn->key_type = ev->key_type;
2683
David Herrmann76a68ba2013-04-06 20:28:37 +02002684 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002685 }
2686
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002687 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002688 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002689 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002690
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002691 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002692}
2693
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002694static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002695{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002696 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002697 struct hci_conn *conn;
2698
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002699 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002700
2701 hci_dev_lock(hdev);
2702
2703 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704 if (conn && !ev->status) {
2705 struct inquiry_entry *ie;
2706
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002707 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2708 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002709 ie->data.clock_offset = ev->clock_offset;
2710 ie->timestamp = jiffies;
2711 }
2712 }
2713
2714 hci_dev_unlock(hdev);
2715}
2716
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002717static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002718{
2719 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2720 struct hci_conn *conn;
2721
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002722 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002723
2724 hci_dev_lock(hdev);
2725
2726 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2727 if (conn && !ev->status)
2728 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2729
2730 hci_dev_unlock(hdev);
2731}
2732
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002733static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002734{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002735 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002736 struct inquiry_entry *ie;
2737
2738 BT_DBG("%s", hdev->name);
2739
2740 hci_dev_lock(hdev);
2741
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002742 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2743 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002744 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2745 ie->timestamp = jiffies;
2746 }
2747
2748 hci_dev_unlock(hdev);
2749}
2750
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002751static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2752 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002753{
2754 struct inquiry_data data;
2755 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002756 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002757
2758 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2759
2760 if (!num_rsp)
2761 return;
2762
Andre Guedes1519cc12012-03-21 00:03:38 -03002763 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2764 return;
2765
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002766 hci_dev_lock(hdev);
2767
2768 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002769 struct inquiry_info_with_rssi_and_pscan_mode *info;
2770 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002771
Johan Hedberge17acd42011-03-30 23:57:16 +03002772 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002773 bacpy(&data.bdaddr, &info->bdaddr);
2774 data.pscan_rep_mode = info->pscan_rep_mode;
2775 data.pscan_period_mode = info->pscan_period_mode;
2776 data.pscan_mode = info->pscan_mode;
2777 memcpy(data.dev_class, info->dev_class, 3);
2778 data.clock_offset = info->clock_offset;
2779 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002780 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002781
2782 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002783 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002784 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002785 info->dev_class, info->rssi,
2786 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002787 }
2788 } else {
2789 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2790
Johan Hedberge17acd42011-03-30 23:57:16 +03002791 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002792 bacpy(&data.bdaddr, &info->bdaddr);
2793 data.pscan_rep_mode = info->pscan_rep_mode;
2794 data.pscan_period_mode = info->pscan_period_mode;
2795 data.pscan_mode = 0x00;
2796 memcpy(data.dev_class, info->dev_class, 3);
2797 data.clock_offset = info->clock_offset;
2798 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002799 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002800 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002801 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002802 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002803 info->dev_class, info->rssi,
2804 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002805 }
2806 }
2807
2808 hci_dev_unlock(hdev);
2809}
2810
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002811static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2812 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002813{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002814 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2815 struct hci_conn *conn;
2816
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002817 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002818
Marcel Holtmann41a96212008-07-14 20:13:48 +02002819 hci_dev_lock(hdev);
2820
2821 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002822 if (!conn)
2823 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002824
Johan Hedbergcad718e2013-04-17 15:00:51 +03002825 if (ev->page < HCI_MAX_PAGES)
2826 memcpy(conn->features[ev->page], ev->features, 8);
2827
Johan Hedbergccd556f2010-11-10 17:11:51 +02002828 if (!ev->status && ev->page == 0x01) {
2829 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002830
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002831 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2832 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002833 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002834
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302835 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002836 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302837 } else {
2838 /* It is mandatory by the Bluetooth specification that
2839 * Extended Inquiry Results are only used when Secure
2840 * Simple Pairing is enabled, but some devices violate
2841 * this.
2842 *
2843 * To make these devices work, the internal SSP
2844 * enabled flag needs to be cleared if the remote host
2845 * features do not indicate SSP support */
2846 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2847 }
Marcel Holtmann41a96212008-07-14 20:13:48 +02002848 }
2849
Johan Hedbergccd556f2010-11-10 17:11:51 +02002850 if (conn->state != BT_CONFIG)
2851 goto unlock;
2852
Johan Hedberg671267b2012-05-12 16:11:50 -03002853 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002854 struct hci_cp_remote_name_req cp;
2855 memset(&cp, 0, sizeof(cp));
2856 bacpy(&cp.bdaddr, &conn->dst);
2857 cp.pscan_rep_mode = 0x02;
2858 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002859 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2860 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002861 conn->dst_type, 0, NULL, 0,
2862 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002863
Johan Hedberg127178d2010-11-18 22:22:29 +02002864 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002865 conn->state = BT_CONNECTED;
2866 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002867 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002868 }
2869
2870unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002871 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002872}
2873
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002874static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2875 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002876{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002877 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2878 struct hci_conn *conn;
2879
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002880 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002881
2882 hci_dev_lock(hdev);
2883
2884 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002885 if (!conn) {
2886 if (ev->link_type == ESCO_LINK)
2887 goto unlock;
2888
2889 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2890 if (!conn)
2891 goto unlock;
2892
2893 conn->type = SCO_LINK;
2894 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002895
Marcel Holtmann732547f2009-04-19 19:14:14 +02002896 switch (ev->status) {
2897 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002898 conn->handle = __le16_to_cpu(ev->handle);
2899 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002900
2901 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002902 break;
2903
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02002904 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05002905 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002906 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002907 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002908 case 0x1f: /* Unspecified error */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002909 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02002910 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2911 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002912 if (hci_setup_sync(conn, conn->link->handle))
2913 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002914 }
2915 /* fall through */
2916
2917 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002918 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002919 break;
2920 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002921
2922 hci_proto_connect_cfm(conn, ev->status);
2923 if (ev->status)
2924 hci_conn_del(conn);
2925
2926unlock:
2927 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002928}
2929
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07002930static inline size_t eir_get_length(u8 *eir, size_t eir_len)
2931{
2932 size_t parsed = 0;
2933
2934 while (parsed < eir_len) {
2935 u8 field_len = eir[0];
2936
2937 if (field_len == 0)
2938 return parsed;
2939
2940 parsed += field_len + 1;
2941 eir += field_len + 1;
2942 }
2943
2944 return eir_len;
2945}
2946
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002947static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
2948 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002949{
2950 struct inquiry_data data;
2951 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2952 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302953 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002954
2955 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2956
2957 if (!num_rsp)
2958 return;
2959
Andre Guedes1519cc12012-03-21 00:03:38 -03002960 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2961 return;
2962
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002963 hci_dev_lock(hdev);
2964
Johan Hedberge17acd42011-03-30 23:57:16 +03002965 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002966 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002967
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002968 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002969 data.pscan_rep_mode = info->pscan_rep_mode;
2970 data.pscan_period_mode = info->pscan_period_mode;
2971 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002972 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002973 data.clock_offset = info->clock_offset;
2974 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002975 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002976
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002977 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002978 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002979 sizeof(info->data),
2980 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002981 else
2982 name_known = true;
2983
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002984 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002985 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302986 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02002987 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002988 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302989 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002990 }
2991
2992 hci_dev_unlock(hdev);
2993}
2994
Johan Hedberg1c2e0042012-06-08 23:31:13 +08002995static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
2996 struct sk_buff *skb)
2997{
2998 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
2999 struct hci_conn *conn;
3000
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003001 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003002 __le16_to_cpu(ev->handle));
3003
3004 hci_dev_lock(hdev);
3005
3006 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3007 if (!conn)
3008 goto unlock;
3009
3010 if (!ev->status)
3011 conn->sec_level = conn->pending_sec_level;
3012
3013 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3014
3015 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003016 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003017 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003018 goto unlock;
3019 }
3020
3021 if (conn->state == BT_CONFIG) {
3022 if (!ev->status)
3023 conn->state = BT_CONNECTED;
3024
3025 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003026 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003027 } else {
3028 hci_auth_cfm(conn, ev->status);
3029
3030 hci_conn_hold(conn);
3031 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003032 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003033 }
3034
3035unlock:
3036 hci_dev_unlock(hdev);
3037}
3038
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003039static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003040{
3041 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003042 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3043 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003044 /* If both remote and local IO capabilities allow MITM
3045 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003046 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3047 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3048 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003049 else
Mikel Astizacabae92013-06-28 10:56:28 +02003050 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003051 }
3052
3053 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003054 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3055 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003056 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003057
3058 return conn->auth_type;
3059}
3060
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003061static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003062{
3063 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3064 struct hci_conn *conn;
3065
3066 BT_DBG("%s", hdev->name);
3067
3068 hci_dev_lock(hdev);
3069
3070 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003071 if (!conn)
3072 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003073
Johan Hedberg03b555e2011-01-04 15:40:05 +02003074 hci_conn_hold(conn);
3075
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003076 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003077 goto unlock;
3078
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003079 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003080 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003081 struct hci_cp_io_capability_reply cp;
3082
3083 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303084 /* Change the IO capability from KeyboardDisplay
3085 * to DisplayYesNo as it is not supported by BT spec. */
3086 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003087 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003088 conn->auth_type = hci_get_auth_req(conn);
3089 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003090
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003091 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3092 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003093 cp.oob_data = 0x01;
3094 else
3095 cp.oob_data = 0x00;
3096
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003097 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003098 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003099 } else {
3100 struct hci_cp_io_capability_neg_reply cp;
3101
3102 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003103 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003104
3105 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003106 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003107 }
3108
3109unlock:
3110 hci_dev_unlock(hdev);
3111}
3112
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003113static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003114{
3115 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3116 struct hci_conn *conn;
3117
3118 BT_DBG("%s", hdev->name);
3119
3120 hci_dev_lock(hdev);
3121
3122 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3123 if (!conn)
3124 goto unlock;
3125
Johan Hedberg03b555e2011-01-04 15:40:05 +02003126 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003127 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003128 if (ev->oob_data)
3129 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003130
3131unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003132 hci_dev_unlock(hdev);
3133}
3134
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003135static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3136 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003137{
3138 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003139 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003140 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003141
3142 BT_DBG("%s", hdev->name);
3143
3144 hci_dev_lock(hdev);
3145
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003146 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003147 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003148
Johan Hedberg7a828902011-04-28 11:28:53 -07003149 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3150 if (!conn)
3151 goto unlock;
3152
3153 loc_mitm = (conn->auth_type & 0x01);
3154 rem_mitm = (conn->remote_auth & 0x01);
3155
3156 /* If we require MITM but the remote device can't provide that
3157 * (it has NoInputNoOutput) then reject the confirmation
3158 * request. The only exception is when we're dedicated bonding
3159 * initiators (connect_cfm_cb set) since then we always have the MITM
3160 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003161 if (!conn->connect_cfm_cb && loc_mitm &&
3162 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003163 BT_DBG("Rejecting request: remote device can't provide MITM");
3164 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003165 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003166 goto unlock;
3167 }
3168
3169 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003170 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3171 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003172
3173 /* If we're not the initiators request authorization to
3174 * proceed from user space (mgmt_user_confirm with
3175 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003176 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003177 BT_DBG("Confirming auto-accept as acceptor");
3178 confirm_hint = 1;
3179 goto confirm;
3180 }
3181
Johan Hedberg9f616562011-04-28 11:28:54 -07003182 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003183 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003184
3185 if (hdev->auto_accept_delay > 0) {
3186 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
Johan Hedberg7bc18d92013-10-16 18:11:39 +03003187 queue_delayed_work(conn->hdev->workqueue,
3188 &conn->auto_accept_work, delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003189 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}