blob: cfcce448957bff44c9728bc09a44b3ba32884818 [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 Guedes76a388b2013-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 Guedes76a388b2013-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
Johan Hedberg264b8b42014-01-08 16:40:39 +02001188 * devices with sec_level MEDIUM or HIGH or if MITM protection
1189 * is requested.
1190 */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001191 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
Johan Hedberg264b8b42014-01-08 16:40:39 +02001192 conn->pending_sec_level != BT_SECURITY_HIGH &&
1193 conn->pending_sec_level != BT_SECURITY_MEDIUM)
Johan Hedberg392599b2010-11-18 22:22:28 +02001194 return 0;
1195
Johan Hedberg392599b2010-11-18 22:22:28 +02001196 return 1;
1197}
1198
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001199static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001200 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001201{
1202 struct hci_cp_remote_name_req cp;
1203
1204 memset(&cp, 0, sizeof(cp));
1205
1206 bacpy(&cp.bdaddr, &e->data.bdaddr);
1207 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1208 cp.pscan_mode = e->data.pscan_mode;
1209 cp.clock_offset = e->data.clock_offset;
1210
1211 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1212}
1213
Johan Hedbergb644ba32012-01-17 21:48:47 +02001214static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001215{
1216 struct discovery_state *discov = &hdev->discovery;
1217 struct inquiry_entry *e;
1218
Johan Hedbergb644ba32012-01-17 21:48:47 +02001219 if (list_empty(&discov->resolve))
1220 return false;
1221
1222 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001223 if (!e)
1224 return false;
1225
Johan Hedbergb644ba32012-01-17 21:48:47 +02001226 if (hci_resolve_name(hdev, e) == 0) {
1227 e->name_state = NAME_PENDING;
1228 return true;
1229 }
1230
1231 return false;
1232}
1233
1234static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001235 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001236{
1237 struct discovery_state *discov = &hdev->discovery;
1238 struct inquiry_entry *e;
1239
1240 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001241 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1242 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001243
1244 if (discov->state == DISCOVERY_STOPPED)
1245 return;
1246
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001247 if (discov->state == DISCOVERY_STOPPING)
1248 goto discov_complete;
1249
1250 if (discov->state != DISCOVERY_RESOLVING)
1251 return;
1252
1253 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001254 /* If the device was not found in a list of found devices names of which
1255 * are pending. there is no need to continue resolving a next name as it
1256 * will be done upon receiving another Remote Name Request Complete
1257 * Event */
1258 if (!e)
1259 return;
1260
1261 list_del(&e->list);
1262 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001263 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001264 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1265 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001266 } else {
1267 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001268 }
1269
Johan Hedbergb644ba32012-01-17 21:48:47 +02001270 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001271 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001272
1273discov_complete:
1274 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1275}
1276
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001277static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1278{
Johan Hedberg127178d2010-11-18 22:22:29 +02001279 struct hci_cp_remote_name_req *cp;
1280 struct hci_conn *conn;
1281
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001282 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001283
1284 /* If successful wait for the name req complete event before
1285 * checking for the need to do authentication */
1286 if (!status)
1287 return;
1288
1289 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1290 if (!cp)
1291 return;
1292
1293 hci_dev_lock(hdev);
1294
1295 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001296
1297 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1298 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1299
Johan Hedberg79c6c702011-04-28 11:28:55 -07001300 if (!conn)
1301 goto unlock;
1302
1303 if (!hci_outgoing_auth_needed(hdev, conn))
1304 goto unlock;
1305
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001306 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001307 struct hci_cp_auth_requested auth_cp;
1308
1309 auth_cp.handle = __cpu_to_le16(conn->handle);
1310 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1311 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001312 }
1313
Johan Hedberg79c6c702011-04-28 11:28:55 -07001314unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001315 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001316}
1317
Marcel Holtmann769be972008-07-14 20:13:49 +02001318static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1319{
1320 struct hci_cp_read_remote_features *cp;
1321 struct hci_conn *conn;
1322
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001323 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001324
1325 if (!status)
1326 return;
1327
1328 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1329 if (!cp)
1330 return;
1331
1332 hci_dev_lock(hdev);
1333
1334 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1335 if (conn) {
1336 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001337 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001338 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001339 }
1340 }
1341
1342 hci_dev_unlock(hdev);
1343}
1344
1345static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1346{
1347 struct hci_cp_read_remote_ext_features *cp;
1348 struct hci_conn *conn;
1349
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001350 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001351
1352 if (!status)
1353 return;
1354
1355 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1356 if (!cp)
1357 return;
1358
1359 hci_dev_lock(hdev);
1360
1361 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1362 if (conn) {
1363 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001364 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001365 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001366 }
1367 }
1368
1369 hci_dev_unlock(hdev);
1370}
1371
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001372static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1373{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001374 struct hci_cp_setup_sync_conn *cp;
1375 struct hci_conn *acl, *sco;
1376 __u16 handle;
1377
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001378 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001379
1380 if (!status)
1381 return;
1382
1383 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1384 if (!cp)
1385 return;
1386
1387 handle = __le16_to_cpu(cp->handle);
1388
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001389 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001390
1391 hci_dev_lock(hdev);
1392
1393 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001394 if (acl) {
1395 sco = acl->link;
1396 if (sco) {
1397 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001398
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001399 hci_proto_connect_cfm(sco, status);
1400 hci_conn_del(sco);
1401 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001402 }
1403
1404 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001405}
1406
1407static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1408{
1409 struct hci_cp_sniff_mode *cp;
1410 struct hci_conn *conn;
1411
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001412 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001413
1414 if (!status)
1415 return;
1416
1417 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1418 if (!cp)
1419 return;
1420
1421 hci_dev_lock(hdev);
1422
1423 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001424 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001425 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001426
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001427 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001428 hci_sco_setup(conn, status);
1429 }
1430
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001431 hci_dev_unlock(hdev);
1432}
1433
1434static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1435{
1436 struct hci_cp_exit_sniff_mode *cp;
1437 struct hci_conn *conn;
1438
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001439 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001440
1441 if (!status)
1442 return;
1443
1444 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1445 if (!cp)
1446 return;
1447
1448 hci_dev_lock(hdev);
1449
1450 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001451 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001452 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001453
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001454 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001455 hci_sco_setup(conn, status);
1456 }
1457
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001458 hci_dev_unlock(hdev);
1459}
1460
Johan Hedberg88c3df12012-02-09 14:27:38 +02001461static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1462{
1463 struct hci_cp_disconnect *cp;
1464 struct hci_conn *conn;
1465
1466 if (!status)
1467 return;
1468
1469 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1470 if (!cp)
1471 return;
1472
1473 hci_dev_lock(hdev);
1474
1475 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1476 if (conn)
1477 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001478 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001479
1480 hci_dev_unlock(hdev);
1481}
1482
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001483static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1484{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001485 struct hci_cp_create_phy_link *cp;
1486
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001487 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001488
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001489 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1490 if (!cp)
1491 return;
1492
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001493 hci_dev_lock(hdev);
1494
1495 if (status) {
1496 struct hci_conn *hcon;
1497
1498 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1499 if (hcon)
1500 hci_conn_del(hcon);
1501 } else {
1502 amp_write_remote_assoc(hdev, cp->phy_handle);
1503 }
1504
1505 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001506}
1507
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001508static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1509{
1510 struct hci_cp_accept_phy_link *cp;
1511
1512 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1513
1514 if (status)
1515 return;
1516
1517 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1518 if (!cp)
1519 return;
1520
1521 amp_write_remote_assoc(hdev, cp->phy_handle);
1522}
1523
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001524static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001525{
1526 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001527 struct discovery_state *discov = &hdev->discovery;
1528 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001529
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001530 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001531
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001532 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001533
1534 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1535 return;
1536
Andre Guedes3e13fa12013-03-27 20:04:56 -03001537 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1538 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1539
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001540 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001541 return;
1542
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001543 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001544
Andre Guedes343f9352012-02-17 20:39:37 -03001545 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001546 goto unlock;
1547
1548 if (list_empty(&discov->resolve)) {
1549 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1550 goto unlock;
1551 }
1552
1553 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1554 if (e && hci_resolve_name(hdev, e) == 0) {
1555 e->name_state = NAME_PENDING;
1556 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1557 } else {
1558 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1559 }
1560
1561unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001562 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001563}
1564
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001565static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001567 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001568 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569 int num_rsp = *((__u8 *) skb->data);
1570
1571 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1572
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001573 if (!num_rsp)
1574 return;
1575
Andre Guedes1519cc12012-03-21 00:03:38 -03001576 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1577 return;
1578
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001580
Johan Hedberge17acd42011-03-30 23:57:16 +03001581 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001582 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001583
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 bacpy(&data.bdaddr, &info->bdaddr);
1585 data.pscan_rep_mode = info->pscan_rep_mode;
1586 data.pscan_period_mode = info->pscan_period_mode;
1587 data.pscan_mode = info->pscan_mode;
1588 memcpy(data.dev_class, info->dev_class, 3);
1589 data.clock_offset = info->clock_offset;
1590 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001591 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001592
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001593 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001594 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001595 info->dev_class, 0, !name_known, ssp, NULL,
1596 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001598
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599 hci_dev_unlock(hdev);
1600}
1601
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001602static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001604 struct hci_ev_conn_complete *ev = (void *) skb->data;
1605 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001607 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001608
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001610
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001611 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001612 if (!conn) {
1613 if (ev->link_type != SCO_LINK)
1614 goto unlock;
1615
1616 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1617 if (!conn)
1618 goto unlock;
1619
1620 conn->type = SCO_LINK;
1621 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001622
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001623 if (!ev->status) {
1624 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001625
1626 if (conn->type == ACL_LINK) {
1627 conn->state = BT_CONFIG;
1628 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001629
1630 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1631 !hci_find_link_key(hdev, &ev->bdaddr))
1632 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1633 else
1634 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001635 } else
1636 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001637
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001638 hci_conn_add_sysfs(conn);
1639
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001640 if (test_bit(HCI_AUTH, &hdev->flags))
1641 conn->link_mode |= HCI_LM_AUTH;
1642
1643 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1644 conn->link_mode |= HCI_LM_ENCRYPT;
1645
1646 /* Get remote features */
1647 if (conn->type == ACL_LINK) {
1648 struct hci_cp_read_remote_features cp;
1649 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001650 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001651 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001652 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001653
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001654 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001655 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001656 struct hci_cp_change_conn_ptype cp;
1657 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001658 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001659 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1660 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001661 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001662 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001663 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001664 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001665 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001666 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001667 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001668
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001669 if (conn->type == ACL_LINK)
1670 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001671
Marcel Holtmann769be972008-07-14 20:13:49 +02001672 if (ev->status) {
1673 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001674 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001675 } else if (ev->link_type != ACL_LINK)
1676 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001677
1678unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001680
1681 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682}
1683
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001684static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001686 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001688 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001690 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001691 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001693 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1694 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695
Szymon Janc138d22e2011-02-17 16:44:23 +01001696 if ((mask & HCI_LM_ACCEPT) &&
Marcel Holtmannb9ee0a72013-10-17 17:24:13 -07001697 !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001699 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701
1702 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001703
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001704 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1705 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001706 memcpy(ie->data.dev_class, ev->dev_class, 3);
1707
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001708 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1709 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001711 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1712 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001713 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 hci_dev_unlock(hdev);
1715 return;
1716 }
1717 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001718
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001720
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 hci_dev_unlock(hdev);
1722
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001723 if (ev->link_type == ACL_LINK ||
1724 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001725 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001726 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001728 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001730 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1731 cp.role = 0x00; /* Become master */
1732 else
1733 cp.role = 0x01; /* Remain slave */
1734
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001735 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1736 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001737 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001738 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001739 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001740
1741 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001742 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001743
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001744 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1745 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1746 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001747 cp.content_format = cpu_to_le16(hdev->voice_setting);
1748 cp.retrans_effort = 0xff;
1749
1750 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001751 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001752 } else {
1753 conn->state = BT_CONNECT2;
1754 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001755 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 } else {
1757 /* Connection rejected */
1758 struct hci_cp_reject_conn_req cp;
1759
1760 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001761 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001762 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763 }
1764}
1765
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001766static u8 hci_to_mgmt_reason(u8 err)
1767{
1768 switch (err) {
1769 case HCI_ERROR_CONNECTION_TIMEOUT:
1770 return MGMT_DEV_DISCONN_TIMEOUT;
1771 case HCI_ERROR_REMOTE_USER_TERM:
1772 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1773 case HCI_ERROR_REMOTE_POWER_OFF:
1774 return MGMT_DEV_DISCONN_REMOTE;
1775 case HCI_ERROR_LOCAL_HOST_TERM:
1776 return MGMT_DEV_DISCONN_LOCAL_HOST;
1777 default:
1778 return MGMT_DEV_DISCONN_UNKNOWN;
1779 }
1780}
1781
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001782static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001784 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Andre Guedesabf54a52013-11-07 17:36:09 -03001785 u8 reason = hci_to_mgmt_reason(ev->reason);
Marcel Holtmann04837f62006-07-03 10:02:33 +02001786 struct hci_conn *conn;
Andre Guedes38462202013-11-07 17:36:10 -03001787 u8 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001789 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 hci_dev_lock(hdev);
1792
Marcel Holtmann04837f62006-07-03 10:02:33 +02001793 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001794 if (!conn)
1795 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001796
Andre Guedesabf54a52013-11-07 17:36:09 -03001797 if (ev->status) {
1798 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1799 conn->dst_type, ev->status);
1800 goto unlock;
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001801 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001802
Andre Guedes38462202013-11-07 17:36:10 -03001803 conn->state = BT_CLOSED;
1804
Andre Guedesabf54a52013-11-07 17:36:09 -03001805 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1806 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
1807 conn->dst_type, reason);
1808
Andre Guedes38462202013-11-07 17:36:10 -03001809 if (conn->type == ACL_LINK && conn->flush_key)
1810 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg22102462013-10-05 12:01:06 +02001811
Andre Guedes38462202013-11-07 17:36:10 -03001812 type = conn->type;
Johan Hedberg22102462013-10-05 12:01:06 +02001813
Andre Guedes38462202013-11-07 17:36:10 -03001814 hci_proto_disconn_cfm(conn, ev->reason);
1815 hci_conn_del(conn);
1816
1817 /* Re-enable advertising if necessary, since it might
1818 * have been disabled by the connection. From the
1819 * HCI_LE_Set_Advertise_Enable command description in
1820 * the core specification (v4.0):
1821 * "The Controller shall continue advertising until the Host
1822 * issues an LE_Set_Advertise_Enable command with
1823 * Advertising_Enable set to 0x00 (Advertising is disabled)
1824 * or until a connection is created or until the Advertising
1825 * is timed out due to Directed Advertising."
1826 */
1827 if (type == LE_LINK)
1828 mgmt_reenable_advertising(hdev);
Johan Hedbergf7520542011-01-20 12:34:39 +02001829
1830unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 hci_dev_unlock(hdev);
1832}
1833
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001834static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001835{
1836 struct hci_ev_auth_complete *ev = (void *) skb->data;
1837 struct hci_conn *conn;
1838
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001839 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001840
1841 hci_dev_lock(hdev);
1842
1843 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001844 if (!conn)
1845 goto unlock;
1846
1847 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001848 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001849 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001850 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001851 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001852 conn->link_mode |= HCI_LM_AUTH;
1853 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001854 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001855 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001856 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001857 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001858 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001859
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001860 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1861 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001862
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001863 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001864 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001865 struct hci_cp_set_conn_encrypt cp;
1866 cp.handle = ev->handle;
1867 cp.encrypt = 0x01;
1868 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001869 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001870 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001871 conn->state = BT_CONNECTED;
1872 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001873 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001874 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001875 } else {
1876 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001877
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001878 hci_conn_hold(conn);
1879 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001880 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001881 }
1882
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001883 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001884 if (!ev->status) {
1885 struct hci_cp_set_conn_encrypt cp;
1886 cp.handle = ev->handle;
1887 cp.encrypt = 0x01;
1888 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001889 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001890 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001891 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001892 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001893 }
1894 }
1895
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001896unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001897 hci_dev_unlock(hdev);
1898}
1899
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001900static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001901{
Johan Hedberg127178d2010-11-18 22:22:29 +02001902 struct hci_ev_remote_name *ev = (void *) skb->data;
1903 struct hci_conn *conn;
1904
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001905 BT_DBG("%s", hdev->name);
1906
1907 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001908
1909 hci_dev_lock(hdev);
1910
1911 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001912
1913 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1914 goto check_auth;
1915
1916 if (ev->status == 0)
1917 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001918 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001919 else
1920 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1921
1922check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001923 if (!conn)
1924 goto unlock;
1925
1926 if (!hci_outgoing_auth_needed(hdev, conn))
1927 goto unlock;
1928
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001929 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001930 struct hci_cp_auth_requested cp;
1931 cp.handle = __cpu_to_le16(conn->handle);
1932 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1933 }
1934
Johan Hedberg79c6c702011-04-28 11:28:55 -07001935unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001936 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001937}
1938
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001939static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001940{
1941 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1942 struct hci_conn *conn;
1943
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001944 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001945
1946 hci_dev_lock(hdev);
1947
1948 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1949 if (conn) {
1950 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001951 if (ev->encrypt) {
1952 /* Encryption implies authentication */
1953 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001954 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001955 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001956 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001957 conn->link_mode &= ~HCI_LM_ENCRYPT;
1958 }
1959
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001960 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001961
Gustavo Padovana7d77232012-05-13 03:20:07 -03001962 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03001963 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02001964 hci_conn_drop(conn);
Gustavo Padovana7d77232012-05-13 03:20:07 -03001965 goto unlock;
1966 }
1967
Marcel Holtmannf8558552008-07-14 20:13:49 +02001968 if (conn->state == BT_CONFIG) {
1969 if (!ev->status)
1970 conn->state = BT_CONNECTED;
1971
1972 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001973 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001974 } else
1975 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001976 }
1977
Gustavo Padovana7d77232012-05-13 03:20:07 -03001978unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001979 hci_dev_unlock(hdev);
1980}
1981
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001982static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
1983 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001984{
1985 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1986 struct hci_conn *conn;
1987
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001988 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001989
1990 hci_dev_lock(hdev);
1991
1992 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1993 if (conn) {
1994 if (!ev->status)
1995 conn->link_mode |= HCI_LM_SECURE;
1996
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001997 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001998
1999 hci_key_change_cfm(conn, ev->status);
2000 }
2001
2002 hci_dev_unlock(hdev);
2003}
2004
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002005static void hci_remote_features_evt(struct hci_dev *hdev,
2006 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002007{
2008 struct hci_ev_remote_features *ev = (void *) skb->data;
2009 struct hci_conn *conn;
2010
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002011 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002012
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002013 hci_dev_lock(hdev);
2014
2015 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002016 if (!conn)
2017 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002018
Johan Hedbergccd556f2010-11-10 17:11:51 +02002019 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002020 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002021
2022 if (conn->state != BT_CONFIG)
2023 goto unlock;
2024
2025 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2026 struct hci_cp_read_remote_ext_features cp;
2027 cp.handle = ev->handle;
2028 cp.page = 0x01;
2029 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002030 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002031 goto unlock;
2032 }
2033
Johan Hedberg671267b2012-05-12 16:11:50 -03002034 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002035 struct hci_cp_remote_name_req cp;
2036 memset(&cp, 0, sizeof(cp));
2037 bacpy(&cp.bdaddr, &conn->dst);
2038 cp.pscan_rep_mode = 0x02;
2039 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002040 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2041 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002042 conn->dst_type, 0, NULL, 0,
2043 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002044
Johan Hedberg127178d2010-11-18 22:22:29 +02002045 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002046 conn->state = BT_CONNECTED;
2047 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002048 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002049 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002050
Johan Hedbergccd556f2010-11-10 17:11:51 +02002051unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002052 hci_dev_unlock(hdev);
2053}
2054
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002055static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002056{
2057 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002058 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002059 __u16 opcode;
2060
2061 skb_pull(skb, sizeof(*ev));
2062
2063 opcode = __le16_to_cpu(ev->opcode);
2064
2065 switch (opcode) {
2066 case HCI_OP_INQUIRY_CANCEL:
2067 hci_cc_inquiry_cancel(hdev, skb);
2068 break;
2069
Andre Guedes4d934832012-03-21 00:03:35 -03002070 case HCI_OP_PERIODIC_INQ:
2071 hci_cc_periodic_inq(hdev, skb);
2072 break;
2073
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002074 case HCI_OP_EXIT_PERIODIC_INQ:
2075 hci_cc_exit_periodic_inq(hdev, skb);
2076 break;
2077
2078 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2079 hci_cc_remote_name_req_cancel(hdev, skb);
2080 break;
2081
2082 case HCI_OP_ROLE_DISCOVERY:
2083 hci_cc_role_discovery(hdev, skb);
2084 break;
2085
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002086 case HCI_OP_READ_LINK_POLICY:
2087 hci_cc_read_link_policy(hdev, skb);
2088 break;
2089
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002090 case HCI_OP_WRITE_LINK_POLICY:
2091 hci_cc_write_link_policy(hdev, skb);
2092 break;
2093
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002094 case HCI_OP_READ_DEF_LINK_POLICY:
2095 hci_cc_read_def_link_policy(hdev, skb);
2096 break;
2097
2098 case HCI_OP_WRITE_DEF_LINK_POLICY:
2099 hci_cc_write_def_link_policy(hdev, skb);
2100 break;
2101
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002102 case HCI_OP_RESET:
2103 hci_cc_reset(hdev, skb);
2104 break;
2105
2106 case HCI_OP_WRITE_LOCAL_NAME:
2107 hci_cc_write_local_name(hdev, skb);
2108 break;
2109
2110 case HCI_OP_READ_LOCAL_NAME:
2111 hci_cc_read_local_name(hdev, skb);
2112 break;
2113
2114 case HCI_OP_WRITE_AUTH_ENABLE:
2115 hci_cc_write_auth_enable(hdev, skb);
2116 break;
2117
2118 case HCI_OP_WRITE_ENCRYPT_MODE:
2119 hci_cc_write_encrypt_mode(hdev, skb);
2120 break;
2121
2122 case HCI_OP_WRITE_SCAN_ENABLE:
2123 hci_cc_write_scan_enable(hdev, skb);
2124 break;
2125
2126 case HCI_OP_READ_CLASS_OF_DEV:
2127 hci_cc_read_class_of_dev(hdev, skb);
2128 break;
2129
2130 case HCI_OP_WRITE_CLASS_OF_DEV:
2131 hci_cc_write_class_of_dev(hdev, skb);
2132 break;
2133
2134 case HCI_OP_READ_VOICE_SETTING:
2135 hci_cc_read_voice_setting(hdev, skb);
2136 break;
2137
2138 case HCI_OP_WRITE_VOICE_SETTING:
2139 hci_cc_write_voice_setting(hdev, skb);
2140 break;
2141
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002142 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2143 hci_cc_read_num_supported_iac(hdev, skb);
2144 break;
2145
Marcel Holtmann333140b2008-07-14 20:13:48 +02002146 case HCI_OP_WRITE_SSP_MODE:
2147 hci_cc_write_ssp_mode(hdev, skb);
2148 break;
2149
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002150 case HCI_OP_READ_LOCAL_VERSION:
2151 hci_cc_read_local_version(hdev, skb);
2152 break;
2153
2154 case HCI_OP_READ_LOCAL_COMMANDS:
2155 hci_cc_read_local_commands(hdev, skb);
2156 break;
2157
2158 case HCI_OP_READ_LOCAL_FEATURES:
2159 hci_cc_read_local_features(hdev, skb);
2160 break;
2161
Andre Guedes971e3a42011-06-30 19:20:52 -03002162 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2163 hci_cc_read_local_ext_features(hdev, skb);
2164 break;
2165
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002166 case HCI_OP_READ_BUFFER_SIZE:
2167 hci_cc_read_buffer_size(hdev, skb);
2168 break;
2169
2170 case HCI_OP_READ_BD_ADDR:
2171 hci_cc_read_bd_addr(hdev, skb);
2172 break;
2173
Johan Hedbergf332ec62013-03-15 17:07:11 -05002174 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2175 hci_cc_read_page_scan_activity(hdev, skb);
2176 break;
2177
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002178 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2179 hci_cc_write_page_scan_activity(hdev, skb);
2180 break;
2181
Johan Hedbergf332ec62013-03-15 17:07:11 -05002182 case HCI_OP_READ_PAGE_SCAN_TYPE:
2183 hci_cc_read_page_scan_type(hdev, skb);
2184 break;
2185
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002186 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2187 hci_cc_write_page_scan_type(hdev, skb);
2188 break;
2189
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002190 case HCI_OP_READ_DATA_BLOCK_SIZE:
2191 hci_cc_read_data_block_size(hdev, skb);
2192 break;
2193
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002194 case HCI_OP_READ_FLOW_CONTROL_MODE:
2195 hci_cc_read_flow_control_mode(hdev, skb);
2196 break;
2197
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002198 case HCI_OP_READ_LOCAL_AMP_INFO:
2199 hci_cc_read_local_amp_info(hdev, skb);
2200 break;
2201
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002202 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2203 hci_cc_read_local_amp_assoc(hdev, skb);
2204 break;
2205
Johan Hedbergd5859e22011-01-25 01:19:58 +02002206 case HCI_OP_READ_INQ_RSP_TX_POWER:
2207 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2208 break;
2209
Johan Hedberg980e1a52011-01-22 06:10:07 +02002210 case HCI_OP_PIN_CODE_REPLY:
2211 hci_cc_pin_code_reply(hdev, skb);
2212 break;
2213
2214 case HCI_OP_PIN_CODE_NEG_REPLY:
2215 hci_cc_pin_code_neg_reply(hdev, skb);
2216 break;
2217
Szymon Jancc35938b2011-03-22 13:12:21 +01002218 case HCI_OP_READ_LOCAL_OOB_DATA:
2219 hci_cc_read_local_oob_data_reply(hdev, skb);
2220 break;
2221
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002222 case HCI_OP_LE_READ_BUFFER_SIZE:
2223 hci_cc_le_read_buffer_size(hdev, skb);
2224 break;
2225
Johan Hedberg60e77322013-01-22 14:01:59 +02002226 case HCI_OP_LE_READ_LOCAL_FEATURES:
2227 hci_cc_le_read_local_features(hdev, skb);
2228 break;
2229
Johan Hedberg8fa19092012-10-19 20:57:49 +03002230 case HCI_OP_LE_READ_ADV_TX_POWER:
2231 hci_cc_le_read_adv_tx_power(hdev, skb);
2232 break;
2233
Johan Hedberga5c29682011-02-19 12:05:57 -03002234 case HCI_OP_USER_CONFIRM_REPLY:
2235 hci_cc_user_confirm_reply(hdev, skb);
2236 break;
2237
2238 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2239 hci_cc_user_confirm_neg_reply(hdev, skb);
2240 break;
2241
Brian Gix1143d452011-11-23 08:28:34 -08002242 case HCI_OP_USER_PASSKEY_REPLY:
2243 hci_cc_user_passkey_reply(hdev, skb);
2244 break;
2245
2246 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2247 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002248 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002249
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002250 case HCI_OP_LE_SET_ADV_ENABLE:
2251 hci_cc_le_set_adv_enable(hdev, skb);
2252 break;
2253
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002254 case HCI_OP_LE_SET_SCAN_ENABLE:
2255 hci_cc_le_set_scan_enable(hdev, skb);
2256 break;
2257
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002258 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2259 hci_cc_le_read_white_list_size(hdev, skb);
2260 break;
2261
Johan Hedberg9b008c02013-01-22 14:02:01 +02002262 case HCI_OP_LE_READ_SUPPORTED_STATES:
2263 hci_cc_le_read_supported_states(hdev, skb);
2264 break;
2265
Andre Guedesf9b49302011-06-30 19:20:53 -03002266 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2267 hci_cc_write_le_host_supported(hdev, skb);
2268 break;
2269
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002270 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2271 hci_cc_write_remote_amp_assoc(hdev, skb);
2272 break;
2273
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002274 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002275 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002276 break;
2277 }
2278
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002279 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002280 del_timer(&hdev->cmd_timer);
2281
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002282 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002283
Szymon Jancdbccd792012-12-11 08:51:19 +01002284 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002285 atomic_set(&hdev->cmd_cnt, 1);
2286 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002287 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002288 }
2289}
2290
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002291static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002292{
2293 struct hci_ev_cmd_status *ev = (void *) skb->data;
2294 __u16 opcode;
2295
2296 skb_pull(skb, sizeof(*ev));
2297
2298 opcode = __le16_to_cpu(ev->opcode);
2299
2300 switch (opcode) {
2301 case HCI_OP_INQUIRY:
2302 hci_cs_inquiry(hdev, ev->status);
2303 break;
2304
2305 case HCI_OP_CREATE_CONN:
2306 hci_cs_create_conn(hdev, ev->status);
2307 break;
2308
2309 case HCI_OP_ADD_SCO:
2310 hci_cs_add_sco(hdev, ev->status);
2311 break;
2312
Marcel Holtmannf8558552008-07-14 20:13:49 +02002313 case HCI_OP_AUTH_REQUESTED:
2314 hci_cs_auth_requested(hdev, ev->status);
2315 break;
2316
2317 case HCI_OP_SET_CONN_ENCRYPT:
2318 hci_cs_set_conn_encrypt(hdev, ev->status);
2319 break;
2320
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002321 case HCI_OP_REMOTE_NAME_REQ:
2322 hci_cs_remote_name_req(hdev, ev->status);
2323 break;
2324
Marcel Holtmann769be972008-07-14 20:13:49 +02002325 case HCI_OP_READ_REMOTE_FEATURES:
2326 hci_cs_read_remote_features(hdev, ev->status);
2327 break;
2328
2329 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2330 hci_cs_read_remote_ext_features(hdev, ev->status);
2331 break;
2332
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002333 case HCI_OP_SETUP_SYNC_CONN:
2334 hci_cs_setup_sync_conn(hdev, ev->status);
2335 break;
2336
2337 case HCI_OP_SNIFF_MODE:
2338 hci_cs_sniff_mode(hdev, ev->status);
2339 break;
2340
2341 case HCI_OP_EXIT_SNIFF_MODE:
2342 hci_cs_exit_sniff_mode(hdev, ev->status);
2343 break;
2344
Johan Hedberg8962ee72011-01-20 12:40:27 +02002345 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002346 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002347 break;
2348
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002349 case HCI_OP_CREATE_PHY_LINK:
2350 hci_cs_create_phylink(hdev, ev->status);
2351 break;
2352
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002353 case HCI_OP_ACCEPT_PHY_LINK:
2354 hci_cs_accept_phylink(hdev, ev->status);
2355 break;
2356
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002357 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002358 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002359 break;
2360 }
2361
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002362 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002363 del_timer(&hdev->cmd_timer);
2364
Johan Hedberg02350a72013-04-03 21:50:29 +03002365 if (ev->status ||
2366 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2367 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002368
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002369 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002370 atomic_set(&hdev->cmd_cnt, 1);
2371 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002372 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002373 }
2374}
2375
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002376static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002377{
2378 struct hci_ev_role_change *ev = (void *) skb->data;
2379 struct hci_conn *conn;
2380
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002381 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002382
2383 hci_dev_lock(hdev);
2384
2385 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2386 if (conn) {
2387 if (!ev->status) {
2388 if (ev->role)
2389 conn->link_mode &= ~HCI_LM_MASTER;
2390 else
2391 conn->link_mode |= HCI_LM_MASTER;
2392 }
2393
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002394 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002395
2396 hci_role_switch_cfm(conn, ev->status, ev->role);
2397 }
2398
2399 hci_dev_unlock(hdev);
2400}
2401
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002402static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002403{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002404 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405 int i;
2406
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002407 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2408 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2409 return;
2410 }
2411
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002412 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002413 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002414 BT_DBG("%s bad parameters", hdev->name);
2415 return;
2416 }
2417
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002418 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2419
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002420 for (i = 0; i < ev->num_hndl; i++) {
2421 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002422 struct hci_conn *conn;
2423 __u16 handle, count;
2424
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002425 handle = __le16_to_cpu(info->handle);
2426 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002427
2428 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002429 if (!conn)
2430 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002431
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002432 conn->sent -= count;
2433
2434 switch (conn->type) {
2435 case ACL_LINK:
2436 hdev->acl_cnt += count;
2437 if (hdev->acl_cnt > hdev->acl_pkts)
2438 hdev->acl_cnt = hdev->acl_pkts;
2439 break;
2440
2441 case LE_LINK:
2442 if (hdev->le_pkts) {
2443 hdev->le_cnt += count;
2444 if (hdev->le_cnt > hdev->le_pkts)
2445 hdev->le_cnt = hdev->le_pkts;
2446 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002447 hdev->acl_cnt += count;
2448 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449 hdev->acl_cnt = hdev->acl_pkts;
2450 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002451 break;
2452
2453 case SCO_LINK:
2454 hdev->sco_cnt += count;
2455 if (hdev->sco_cnt > hdev->sco_pkts)
2456 hdev->sco_cnt = hdev->sco_pkts;
2457 break;
2458
2459 default:
2460 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2461 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002462 }
2463 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002464
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002465 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002466}
2467
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002468static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2469 __u16 handle)
2470{
2471 struct hci_chan *chan;
2472
2473 switch (hdev->dev_type) {
2474 case HCI_BREDR:
2475 return hci_conn_hash_lookup_handle(hdev, handle);
2476 case HCI_AMP:
2477 chan = hci_chan_lookup_handle(hdev, handle);
2478 if (chan)
2479 return chan->conn;
2480 break;
2481 default:
2482 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2483 break;
2484 }
2485
2486 return NULL;
2487}
2488
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002489static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002490{
2491 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2492 int i;
2493
2494 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2495 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2496 return;
2497 }
2498
2499 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002500 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002501 BT_DBG("%s bad parameters", hdev->name);
2502 return;
2503 }
2504
2505 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002506 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002507
2508 for (i = 0; i < ev->num_hndl; i++) {
2509 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002510 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002511 __u16 handle, block_count;
2512
2513 handle = __le16_to_cpu(info->handle);
2514 block_count = __le16_to_cpu(info->blocks);
2515
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002516 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002517 if (!conn)
2518 continue;
2519
2520 conn->sent -= block_count;
2521
2522 switch (conn->type) {
2523 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002524 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002525 hdev->block_cnt += block_count;
2526 if (hdev->block_cnt > hdev->num_blocks)
2527 hdev->block_cnt = hdev->num_blocks;
2528 break;
2529
2530 default:
2531 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2532 break;
2533 }
2534 }
2535
2536 queue_work(hdev->workqueue, &hdev->tx_work);
2537}
2538
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002539static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002540{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002541 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002542 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002544 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002545
2546 hci_dev_lock(hdev);
2547
Marcel Holtmann04837f62006-07-03 10:02:33 +02002548 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2549 if (conn) {
2550 conn->mode = ev->mode;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002551
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002552 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2553 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002554 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002555 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002556 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002557 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002558 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002559
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002560 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002561 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002562 }
2563
2564 hci_dev_unlock(hdev);
2565}
2566
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002567static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002569 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2570 struct hci_conn *conn;
2571
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002572 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002573
2574 hci_dev_lock(hdev);
2575
2576 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002577 if (!conn)
2578 goto unlock;
2579
2580 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002581 hci_conn_hold(conn);
2582 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002583 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002584 }
2585
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002586 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002587 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002588 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002589 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002590 u8 secure;
2591
2592 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2593 secure = 1;
2594 else
2595 secure = 0;
2596
Johan Hedberg744cf192011-11-08 20:40:14 +02002597 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002598 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002599
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002600unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002601 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602}
2603
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002604static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002605{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002606 struct hci_ev_link_key_req *ev = (void *) skb->data;
2607 struct hci_cp_link_key_reply cp;
2608 struct hci_conn *conn;
2609 struct link_key *key;
2610
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002611 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002612
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002613 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002614 return;
2615
2616 hci_dev_lock(hdev);
2617
2618 key = hci_find_link_key(hdev, &ev->bdaddr);
2619 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002620 BT_DBG("%s link key not found for %pMR", hdev->name,
2621 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002622 goto not_found;
2623 }
2624
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002625 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2626 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002627
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002628 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002629 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002630 BT_DBG("%s ignoring debug key", hdev->name);
2631 goto not_found;
2632 }
2633
2634 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002635 if (conn) {
2636 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002637 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002638 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2639 goto not_found;
2640 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002641
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002642 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002643 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002644 BT_DBG("%s ignoring key unauthenticated for high security",
2645 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002646 goto not_found;
2647 }
2648
2649 conn->key_type = key->type;
2650 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002651 }
2652
2653 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002654 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002655
2656 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2657
2658 hci_dev_unlock(hdev);
2659
2660 return;
2661
2662not_found:
2663 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2664 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665}
2666
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002667static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002668{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002669 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2670 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002671 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002672
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002673 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002674
2675 hci_dev_lock(hdev);
2676
2677 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2678 if (conn) {
2679 hci_conn_hold(conn);
2680 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002681 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002682
2683 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2684 conn->key_type = ev->key_type;
2685
David Herrmann76a68ba2013-04-06 20:28:37 +02002686 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002687 }
2688
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002689 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002690 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002691 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002692
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002693 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002694}
2695
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002696static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002697{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002698 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002699 struct hci_conn *conn;
2700
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002701 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002702
2703 hci_dev_lock(hdev);
2704
2705 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706 if (conn && !ev->status) {
2707 struct inquiry_entry *ie;
2708
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002709 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2710 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002711 ie->data.clock_offset = ev->clock_offset;
2712 ie->timestamp = jiffies;
2713 }
2714 }
2715
2716 hci_dev_unlock(hdev);
2717}
2718
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002719static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002720{
2721 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2722 struct hci_conn *conn;
2723
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002724 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002725
2726 hci_dev_lock(hdev);
2727
2728 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2729 if (conn && !ev->status)
2730 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2731
2732 hci_dev_unlock(hdev);
2733}
2734
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002735static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002736{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002737 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002738 struct inquiry_entry *ie;
2739
2740 BT_DBG("%s", hdev->name);
2741
2742 hci_dev_lock(hdev);
2743
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002744 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2745 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002746 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2747 ie->timestamp = jiffies;
2748 }
2749
2750 hci_dev_unlock(hdev);
2751}
2752
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002753static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2754 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002755{
2756 struct inquiry_data data;
2757 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002758 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002759
2760 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2761
2762 if (!num_rsp)
2763 return;
2764
Andre Guedes1519cc12012-03-21 00:03:38 -03002765 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2766 return;
2767
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002768 hci_dev_lock(hdev);
2769
2770 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002771 struct inquiry_info_with_rssi_and_pscan_mode *info;
2772 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002773
Johan Hedberge17acd42011-03-30 23:57:16 +03002774 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002775 bacpy(&data.bdaddr, &info->bdaddr);
2776 data.pscan_rep_mode = info->pscan_rep_mode;
2777 data.pscan_period_mode = info->pscan_period_mode;
2778 data.pscan_mode = info->pscan_mode;
2779 memcpy(data.dev_class, info->dev_class, 3);
2780 data.clock_offset = info->clock_offset;
2781 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002782 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002783
2784 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002785 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002786 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002787 info->dev_class, info->rssi,
2788 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002789 }
2790 } else {
2791 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2792
Johan Hedberge17acd42011-03-30 23:57:16 +03002793 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002794 bacpy(&data.bdaddr, &info->bdaddr);
2795 data.pscan_rep_mode = info->pscan_rep_mode;
2796 data.pscan_period_mode = info->pscan_period_mode;
2797 data.pscan_mode = 0x00;
2798 memcpy(data.dev_class, info->dev_class, 3);
2799 data.clock_offset = info->clock_offset;
2800 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002801 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002802 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002803 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002804 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002805 info->dev_class, info->rssi,
2806 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002807 }
2808 }
2809
2810 hci_dev_unlock(hdev);
2811}
2812
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002813static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2814 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002815{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002816 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2817 struct hci_conn *conn;
2818
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002819 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002820
Marcel Holtmann41a96212008-07-14 20:13:48 +02002821 hci_dev_lock(hdev);
2822
2823 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002824 if (!conn)
2825 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002826
Johan Hedbergcad718e2013-04-17 15:00:51 +03002827 if (ev->page < HCI_MAX_PAGES)
2828 memcpy(conn->features[ev->page], ev->features, 8);
2829
Johan Hedbergccd556f2010-11-10 17:11:51 +02002830 if (!ev->status && ev->page == 0x01) {
2831 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002832
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002833 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2834 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002835 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002836
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302837 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002838 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302839 } else {
2840 /* It is mandatory by the Bluetooth specification that
2841 * Extended Inquiry Results are only used when Secure
2842 * Simple Pairing is enabled, but some devices violate
2843 * this.
2844 *
2845 * To make these devices work, the internal SSP
2846 * enabled flag needs to be cleared if the remote host
2847 * features do not indicate SSP support */
2848 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2849 }
Marcel Holtmann41a96212008-07-14 20:13:48 +02002850 }
2851
Johan Hedbergccd556f2010-11-10 17:11:51 +02002852 if (conn->state != BT_CONFIG)
2853 goto unlock;
2854
Johan Hedberg671267b2012-05-12 16:11:50 -03002855 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002856 struct hci_cp_remote_name_req cp;
2857 memset(&cp, 0, sizeof(cp));
2858 bacpy(&cp.bdaddr, &conn->dst);
2859 cp.pscan_rep_mode = 0x02;
2860 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002861 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2862 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002863 conn->dst_type, 0, NULL, 0,
2864 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002865
Johan Hedberg127178d2010-11-18 22:22:29 +02002866 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002867 conn->state = BT_CONNECTED;
2868 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002869 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002870 }
2871
2872unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002873 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002874}
2875
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002876static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2877 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002878{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002879 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2880 struct hci_conn *conn;
2881
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002882 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002883
2884 hci_dev_lock(hdev);
2885
2886 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002887 if (!conn) {
2888 if (ev->link_type == ESCO_LINK)
2889 goto unlock;
2890
2891 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2892 if (!conn)
2893 goto unlock;
2894
2895 conn->type = SCO_LINK;
2896 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002897
Marcel Holtmann732547f2009-04-19 19:14:14 +02002898 switch (ev->status) {
2899 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002900 conn->handle = __le16_to_cpu(ev->handle);
2901 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002902
2903 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002904 break;
2905
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02002906 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05002907 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002908 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002909 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002910 case 0x1f: /* Unspecified error */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002911 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02002912 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2913 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002914 if (hci_setup_sync(conn, conn->link->handle))
2915 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002916 }
2917 /* fall through */
2918
2919 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002920 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002921 break;
2922 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002923
2924 hci_proto_connect_cfm(conn, ev->status);
2925 if (ev->status)
2926 hci_conn_del(conn);
2927
2928unlock:
2929 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002930}
2931
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07002932static inline size_t eir_get_length(u8 *eir, size_t eir_len)
2933{
2934 size_t parsed = 0;
2935
2936 while (parsed < eir_len) {
2937 u8 field_len = eir[0];
2938
2939 if (field_len == 0)
2940 return parsed;
2941
2942 parsed += field_len + 1;
2943 eir += field_len + 1;
2944 }
2945
2946 return eir_len;
2947}
2948
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002949static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
2950 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002951{
2952 struct inquiry_data data;
2953 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2954 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302955 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002956
2957 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2958
2959 if (!num_rsp)
2960 return;
2961
Andre Guedes1519cc12012-03-21 00:03:38 -03002962 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2963 return;
2964
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002965 hci_dev_lock(hdev);
2966
Johan Hedberge17acd42011-03-30 23:57:16 +03002967 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002968 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002969
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002970 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002971 data.pscan_rep_mode = info->pscan_rep_mode;
2972 data.pscan_period_mode = info->pscan_period_mode;
2973 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002974 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002975 data.clock_offset = info->clock_offset;
2976 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002977 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002978
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002979 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002980 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002981 sizeof(info->data),
2982 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002983 else
2984 name_known = true;
2985
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002986 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002987 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302988 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02002989 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002990 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302991 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002992 }
2993
2994 hci_dev_unlock(hdev);
2995}
2996
Johan Hedberg1c2e0042012-06-08 23:31:13 +08002997static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
2998 struct sk_buff *skb)
2999{
3000 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3001 struct hci_conn *conn;
3002
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003003 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003004 __le16_to_cpu(ev->handle));
3005
3006 hci_dev_lock(hdev);
3007
3008 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3009 if (!conn)
3010 goto unlock;
3011
3012 if (!ev->status)
3013 conn->sec_level = conn->pending_sec_level;
3014
3015 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3016
3017 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003018 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003019 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003020 goto unlock;
3021 }
3022
3023 if (conn->state == BT_CONFIG) {
3024 if (!ev->status)
3025 conn->state = BT_CONNECTED;
3026
3027 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003028 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003029 } else {
3030 hci_auth_cfm(conn, ev->status);
3031
3032 hci_conn_hold(conn);
3033 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003034 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003035 }
3036
3037unlock:
3038 hci_dev_unlock(hdev);
3039}
3040
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003041static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003042{
3043 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003044 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3045 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003046 /* If both remote and local IO capabilities allow MITM
3047 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003048 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3049 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3050 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003051 else
Mikel Astizacabae92013-06-28 10:56:28 +02003052 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003053 }
3054
3055 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003056 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3057 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003058 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003059
3060 return conn->auth_type;
3061}
3062
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003063static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003064{
3065 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3066 struct hci_conn *conn;
3067
3068 BT_DBG("%s", hdev->name);
3069
3070 hci_dev_lock(hdev);
3071
3072 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003073 if (!conn)
3074 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003075
Johan Hedberg03b555e2011-01-04 15:40:05 +02003076 hci_conn_hold(conn);
3077
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003078 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003079 goto unlock;
3080
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003081 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003082 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003083 struct hci_cp_io_capability_reply cp;
3084
3085 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303086 /* Change the IO capability from KeyboardDisplay
3087 * to DisplayYesNo as it is not supported by BT spec. */
3088 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003089 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003090 conn->auth_type = hci_get_auth_req(conn);
3091 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003092
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003093 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3094 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003095 cp.oob_data = 0x01;
3096 else
3097 cp.oob_data = 0x00;
3098
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003099 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003100 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003101 } else {
3102 struct hci_cp_io_capability_neg_reply cp;
3103
3104 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003105 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003106
3107 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003108 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003109 }
3110
3111unlock:
3112 hci_dev_unlock(hdev);
3113}
3114
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003115static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003116{
3117 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3118 struct hci_conn *conn;
3119
3120 BT_DBG("%s", hdev->name);
3121
3122 hci_dev_lock(hdev);
3123
3124 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3125 if (!conn)
3126 goto unlock;
3127
Johan Hedberg03b555e2011-01-04 15:40:05 +02003128 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003129 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003130 if (ev->oob_data)
3131 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003132
3133unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003134 hci_dev_unlock(hdev);
3135}
3136
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003137static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3138 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003139{
3140 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003141 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003142 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003143
3144 BT_DBG("%s", hdev->name);
3145
3146 hci_dev_lock(hdev);
3147
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003148 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003149 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003150
Johan Hedberg7a828902011-04-28 11:28:53 -07003151 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3152 if (!conn)
3153 goto unlock;
3154
3155 loc_mitm = (conn->auth_type & 0x01);
3156 rem_mitm = (conn->remote_auth & 0x01);
3157
3158 /* If we require MITM but the remote device can't provide that
3159 * (it has NoInputNoOutput) then reject the confirmation
3160 * request. The only exception is when we're dedicated bonding
3161 * initiators (connect_cfm_cb set) since then we always have the MITM
3162 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003163 if (!conn->connect_cfm_cb && loc_mitm &&
3164 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003165 BT_DBG("Rejecting request: remote device can't provide MITM");
3166 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003167 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003168 goto unlock;
3169 }
3170
3171 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003172 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3173 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003174
3175 /* If we're not the initiators request authorization to
3176 * proceed from user space (mgmt_user_confirm with
3177 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003178 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003179 BT_DBG("Confirming auto-accept as acceptor");
3180 confirm_hint = 1;
3181 goto confirm;
3182 }
3183
Johan Hedberg9f616562011-04-28 11:28:54 -07003184 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003185 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003186
3187 if (hdev->auto_accept_delay > 0) {
3188 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
Johan Hedberg7bc18d92013-10-16 18:11:39 +03003189 queue_delayed_work(conn->hdev->workqueue,
3190 &conn->auto_accept_work, delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003191 goto unlock;
3192 }
3193
Johan Hedberg7a828902011-04-28 11:28:53 -07003194 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003195 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003196 goto unlock;
3197 }
3198
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003199confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003200 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003201 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003202
3203unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003204 hci_dev_unlock(hdev);
3205}
3206
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003207static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3208 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003209{
3210 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3211
3212 BT_DBG("%s", hdev->name);
3213
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003214 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003215 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003216}
3217
Johan Hedberg92a25252012-09-06 18:39:26 +03003218static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3219 struct sk_buff *skb)
3220{
3221 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3222 struct hci_conn *conn;
3223
3224 BT_DBG("%s", hdev->name);
3225
3226 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3227 if (!conn)
3228 return;
3229
3230 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3231 conn->passkey_entered = 0;
3232
3233 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3234 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3235 conn->dst_type, conn->passkey_notify,
3236 conn->passkey_entered);
3237}
3238
3239static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3240{
3241 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3242 struct hci_conn *conn;
3243
3244 BT_DBG("%s", hdev->name);
3245
3246 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3247 if (!conn)
3248 return;
3249
3250 switch (ev->type) {
3251 case HCI_KEYPRESS_STARTED:
3252 conn->passkey_entered = 0;
3253 return;
3254
3255 case HCI_KEYPRESS_ENTERED:
3256 conn->passkey_entered++;
3257 break;
3258
3259 case HCI_KEYPRESS_ERASED:
3260 conn->passkey_entered--;
3261 break;
3262
3263 case HCI_KEYPRESS_CLEARED:
3264 conn->passkey_entered = 0;
3265 break;
3266
3267 case HCI_KEYPRESS_COMPLETED:
3268 return;
3269 }
3270
3271 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3272 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3273 conn->dst_type, conn->passkey_notify,
3274 conn->passkey_entered);
3275}
3276
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003277static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3278 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003279{
3280 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3281 struct hci_conn *conn;
3282
3283 BT_DBG("%s", hdev->name);
3284
3285 hci_dev_lock(hdev);
3286
3287 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003288 if (!conn)
3289 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003290
Johan Hedberg2a611692011-02-19 12:06:00 -03003291 /* To avoid duplicate auth_failed events to user space we check
3292 * the HCI_CONN_AUTH_PEND flag which will be set if we
3293 * initiated the authentication. A traditional auth_complete
3294 * event gets always produced as initiator and is also mapped to
3295 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003296 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003297 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003298 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003299
David Herrmann76a68ba2013-04-06 20:28:37 +02003300 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003301
3302unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003303 hci_dev_unlock(hdev);
3304}
3305
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003306static void hci_remote_host_features_evt(struct hci_dev *hdev,
3307 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003308{
3309 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3310 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003311 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003312
3313 BT_DBG("%s", hdev->name);
3314
3315 hci_dev_lock(hdev);
3316
Johan Hedbergcad718e2013-04-17 15:00:51 +03003317 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3318 if (conn)
3319 memcpy(conn->features[1], ev->features, 8);
3320
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003321 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3322 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003323 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003324
3325 hci_dev_unlock(hdev);
3326}
3327
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003328static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3329 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003330{
3331 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3332 struct oob_data *data;
3333
3334 BT_DBG("%s", hdev->name);
3335
3336 hci_dev_lock(hdev);
3337
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003338 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003339 goto unlock;
3340
Szymon Janc2763eda2011-03-22 13:12:22 +01003341 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3342 if (data) {
3343 struct hci_cp_remote_oob_data_reply cp;
3344
3345 bacpy(&cp.bdaddr, &ev->bdaddr);
3346 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3347 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3348
3349 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003350 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003351 } else {
3352 struct hci_cp_remote_oob_data_neg_reply cp;
3353
3354 bacpy(&cp.bdaddr, &ev->bdaddr);
3355 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003356 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003357 }
3358
Szymon Jance1ba1f12011-04-06 13:01:59 +02003359unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003360 hci_dev_unlock(hdev);
3361}
3362
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003363static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3364 struct sk_buff *skb)
3365{
3366 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3367 struct hci_conn *hcon, *bredr_hcon;
3368
3369 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3370 ev->status);
3371
3372 hci_dev_lock(hdev);
3373
3374 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3375 if (!hcon) {
3376 hci_dev_unlock(hdev);
3377 return;
3378 }
3379
3380 if (ev->status) {
3381 hci_conn_del(hcon);
3382 hci_dev_unlock(hdev);
3383 return;
3384 }
3385
3386 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3387
3388 hcon->state = BT_CONNECTED;
3389 bacpy(&hcon->dst, &bredr_hcon->dst);
3390
3391 hci_conn_hold(hcon);
3392 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003393 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003394
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003395 hci_conn_add_sysfs(hcon);
3396
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003397 amp_physical_cfm(bredr_hcon, hcon);
3398
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003399 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003400}
3401
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003402static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3403{
3404 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3405 struct hci_conn *hcon;
3406 struct hci_chan *hchan;
3407 struct amp_mgr *mgr;
3408
3409 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3410 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3411 ev->status);
3412
3413 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3414 if (!hcon)
3415 return;
3416
3417 /* Create AMP hchan */
3418 hchan = hci_chan_create(hcon);
3419 if (!hchan)
3420 return;
3421
3422 hchan->handle = le16_to_cpu(ev->handle);
3423
3424 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3425
3426 mgr = hcon->amp_mgr;
3427 if (mgr && mgr->bredr_chan) {
3428 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3429
3430 l2cap_chan_lock(bredr_chan);
3431
3432 bredr_chan->conn->mtu = hdev->block_mtu;
3433 l2cap_logical_cfm(bredr_chan, hchan, 0);
3434 hci_conn_hold(hcon);
3435
3436 l2cap_chan_unlock(bredr_chan);
3437 }
3438}
3439
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003440static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3441 struct sk_buff *skb)
3442{
3443 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3444 struct hci_chan *hchan;
3445
3446 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3447 le16_to_cpu(ev->handle), ev->status);
3448
3449 if (ev->status)
3450 return;
3451
3452 hci_dev_lock(hdev);
3453
3454 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3455 if (!hchan)
3456 goto unlock;
3457
3458 amp_destroy_logical_link(hchan, ev->reason);
3459
3460unlock:
3461 hci_dev_unlock(hdev);
3462}
3463
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003464static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3465 struct sk_buff *skb)
3466{
3467 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3468 struct hci_conn *hcon;
3469
3470 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3471
3472 if (ev->status)
3473 return;
3474
3475 hci_dev_lock(hdev);
3476
3477 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3478 if (hcon) {
3479 hcon->state = BT_CLOSED;
3480 hci_conn_del(hcon);
3481 }
3482
3483 hci_dev_unlock(hdev);
3484}
3485
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003486static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003487{
3488 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3489 struct hci_conn *conn;
3490
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003491 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003492
3493 hci_dev_lock(hdev);
3494
Andre Guedesb47a09b2012-07-27 15:10:15 -03003495 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003496 if (!conn) {
3497 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3498 if (!conn) {
3499 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003500 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003501 }
Andre Guedes29b79882011-05-31 14:20:54 -03003502
3503 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003504
Marcel Holtmann880be4e2013-10-13 07:25:18 -07003505 /* The advertising parameters for own address type
3506 * define which source address and source address
3507 * type this connections has.
3508 */
3509 if (bacmp(&conn->src, BDADDR_ANY)) {
3510 conn->src_type = ADDR_LE_DEV_PUBLIC;
3511 } else {
3512 bacpy(&conn->src, &hdev->static_addr);
3513 conn->src_type = ADDR_LE_DEV_RANDOM;
3514 }
3515
Andre Guedesb9b343d2012-07-27 15:10:11 -03003516 if (ev->role == LE_CONN_ROLE_MASTER) {
3517 conn->out = true;
3518 conn->link_mode |= HCI_LM_MASTER;
3519 }
Ville Tervob62f3282011-02-10 22:38:50 -03003520 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003521
Andre Guedescd17dec2012-07-27 15:10:16 -03003522 if (ev->status) {
3523 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3524 conn->dst_type, ev->status);
3525 hci_proto_connect_cfm(conn, ev->status);
3526 conn->state = BT_CLOSED;
3527 hci_conn_del(conn);
3528 goto unlock;
3529 }
3530
Johan Hedbergb644ba32012-01-17 21:48:47 +02003531 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3532 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003533 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003534
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003535 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003536 conn->handle = __le16_to_cpu(ev->handle);
3537 conn->state = BT_CONNECTED;
3538
Jukka Rissanen18722c22013-12-11 17:05:37 +02003539 if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
3540 set_bit(HCI_CONN_6LOWPAN, &conn->flags);
3541
Ville Tervofcd89c02011-02-10 22:38:47 -03003542 hci_conn_add_sysfs(conn);
3543
3544 hci_proto_connect_cfm(conn, ev->status);
3545
3546unlock:
3547 hci_dev_unlock(hdev);
3548}
3549
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003550static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003551{
Andre Guedese95beb42011-09-26 20:48:35 -03003552 u8 num_reports = skb->data[0];
3553 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003554 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003555
Andre Guedese95beb42011-09-26 20:48:35 -03003556 while (num_reports--) {
3557 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003558
Andre Guedes3c9e9192012-01-10 18:20:50 -03003559 rssi = ev->data[ev->length];
3560 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003561 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003562
Andre Guedese95beb42011-09-26 20:48:35 -03003563 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003564 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003565}
3566
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003567static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003568{
3569 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3570 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003571 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003572 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003573 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003574
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003575 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003576
3577 hci_dev_lock(hdev);
3578
3579 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003580 if (conn == NULL)
3581 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003582
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003583 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3584 if (ltk == NULL)
3585 goto not_found;
3586
3587 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003588 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003589
3590 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03003591 conn->pending_sec_level = BT_SECURITY_HIGH;
3592 else
3593 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003594
Andre Guedes89cbb4d2013-07-31 16:25:29 -03003595 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003596
3597 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3598
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003599 if (ltk->type & HCI_SMP_STK) {
3600 list_del(&ltk->list);
3601 kfree(ltk);
3602 }
3603
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003604 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003605
3606 return;
3607
3608not_found:
3609 neg.handle = ev->handle;
3610 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3611 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003612}
3613
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003614static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003615{
3616 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3617
3618 skb_pull(skb, sizeof(*le_ev));
3619
3620 switch (le_ev->subevent) {
3621 case HCI_EV_LE_CONN_COMPLETE:
3622 hci_le_conn_complete_evt(hdev, skb);
3623 break;
3624
Andre Guedes9aa04c92011-05-26 16:23:51 -03003625 case HCI_EV_LE_ADVERTISING_REPORT:
3626 hci_le_adv_report_evt(hdev, skb);
3627 break;
3628
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003629 case HCI_EV_LE_LTK_REQ:
3630 hci_le_ltk_request_evt(hdev, skb);
3631 break;
3632
Ville Tervofcd89c02011-02-10 22:38:47 -03003633 default:
3634 break;
3635 }
3636}
3637
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003638static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3639{
3640 struct hci_ev_channel_selected *ev = (void *) skb->data;
3641 struct hci_conn *hcon;
3642
3643 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3644
3645 skb_pull(skb, sizeof(*ev));
3646
3647 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3648 if (!hcon)
3649 return;
3650
3651 amp_read_loc_assoc_final_data(hdev, hcon);
3652}
3653
Linus Torvalds1da177e2005-04-16 15:20:36 -07003654void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3655{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003656 struct hci_event_hdr *hdr = (void *) skb->data;
3657 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003658
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003659 hci_dev_lock(hdev);
3660
3661 /* Received events are (currently) only needed when a request is
3662 * ongoing so avoid unnecessary memory allocation.
3663 */
3664 if (hdev->req_status == HCI_REQ_PEND) {
3665 kfree_skb(hdev->recv_evt);
3666 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3667 }
3668
3669 hci_dev_unlock(hdev);
3670
Linus Torvalds1da177e2005-04-16 15:20:36 -07003671 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3672
Johan Hedberg02350a72013-04-03 21:50:29 +03003673 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02003674 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
3675 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03003676
3677 hci_req_cmd_complete(hdev, opcode, 0);
3678 }
3679
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003680 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003681 case HCI_EV_INQUIRY_COMPLETE:
3682 hci_inquiry_complete_evt(hdev, skb);
3683 break;
3684
3685 case HCI_EV_INQUIRY_RESULT:
3686 hci_inquiry_result_evt(hdev, skb);
3687 break;
3688
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003689 case HCI_EV_CONN_COMPLETE:
3690 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003691 break;
3692
Linus Torvalds1da177e2005-04-16 15:20:36 -07003693 case HCI_EV_CONN_REQUEST:
3694 hci_conn_request_evt(hdev, skb);
3695 break;
3696
Linus Torvalds1da177e2005-04-16 15:20:36 -07003697 case HCI_EV_DISCONN_COMPLETE:
3698 hci_disconn_complete_evt(hdev, skb);
3699 break;
3700
Linus Torvalds1da177e2005-04-16 15:20:36 -07003701 case HCI_EV_AUTH_COMPLETE:
3702 hci_auth_complete_evt(hdev, skb);
3703 break;
3704
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003705 case HCI_EV_REMOTE_NAME:
3706 hci_remote_name_evt(hdev, skb);
3707 break;
3708
Linus Torvalds1da177e2005-04-16 15:20:36 -07003709 case HCI_EV_ENCRYPT_CHANGE:
3710 hci_encrypt_change_evt(hdev, skb);
3711 break;
3712
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003713 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3714 hci_change_link_key_complete_evt(hdev, skb);
3715 break;
3716
3717 case HCI_EV_REMOTE_FEATURES:
3718 hci_remote_features_evt(hdev, skb);
3719 break;
3720
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003721 case HCI_EV_CMD_COMPLETE:
3722 hci_cmd_complete_evt(hdev, skb);
3723 break;
3724
3725 case HCI_EV_CMD_STATUS:
3726 hci_cmd_status_evt(hdev, skb);
3727 break;
3728
3729 case HCI_EV_ROLE_CHANGE:
3730 hci_role_change_evt(hdev, skb);
3731 break;
3732
3733 case HCI_EV_NUM_COMP_PKTS:
3734 hci_num_comp_pkts_evt(hdev, skb);
3735 break;
3736
3737 case HCI_EV_MODE_CHANGE:
3738 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003739 break;
3740
3741 case HCI_EV_PIN_CODE_REQ:
3742 hci_pin_code_request_evt(hdev, skb);
3743 break;
3744
3745 case HCI_EV_LINK_KEY_REQ:
3746 hci_link_key_request_evt(hdev, skb);
3747 break;
3748
3749 case HCI_EV_LINK_KEY_NOTIFY:
3750 hci_link_key_notify_evt(hdev, skb);
3751 break;
3752
3753 case HCI_EV_CLOCK_OFFSET:
3754 hci_clock_offset_evt(hdev, skb);
3755 break;
3756
Marcel Holtmanna8746412008-07-14 20:13:46 +02003757 case HCI_EV_PKT_TYPE_CHANGE:
3758 hci_pkt_type_change_evt(hdev, skb);
3759 break;
3760
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003761 case HCI_EV_PSCAN_REP_MODE:
3762 hci_pscan_rep_mode_evt(hdev, skb);
3763 break;
3764
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003765 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3766 hci_inquiry_result_with_rssi_evt(hdev, skb);
3767 break;
3768
3769 case HCI_EV_REMOTE_EXT_FEATURES:
3770 hci_remote_ext_features_evt(hdev, skb);
3771 break;
3772
3773 case HCI_EV_SYNC_CONN_COMPLETE:
3774 hci_sync_conn_complete_evt(hdev, skb);
3775 break;
3776
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003777 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3778 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003779 break;
3780
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003781 case HCI_EV_KEY_REFRESH_COMPLETE:
3782 hci_key_refresh_complete_evt(hdev, skb);
3783 break;
3784
Marcel Holtmann04936842008-07-14 20:13:48 +02003785 case HCI_EV_IO_CAPA_REQUEST:
3786 hci_io_capa_request_evt(hdev, skb);
3787 break;
3788
Johan Hedberg03b555e2011-01-04 15:40:05 +02003789 case HCI_EV_IO_CAPA_REPLY:
3790 hci_io_capa_reply_evt(hdev, skb);
3791 break;
3792
Johan Hedberga5c29682011-02-19 12:05:57 -03003793 case HCI_EV_USER_CONFIRM_REQUEST:
3794 hci_user_confirm_request_evt(hdev, skb);
3795 break;
3796
Brian Gix1143d452011-11-23 08:28:34 -08003797 case HCI_EV_USER_PASSKEY_REQUEST:
3798 hci_user_passkey_request_evt(hdev, skb);
3799 break;
3800
Johan Hedberg92a25252012-09-06 18:39:26 +03003801 case HCI_EV_USER_PASSKEY_NOTIFY:
3802 hci_user_passkey_notify_evt(hdev, skb);
3803 break;
3804
3805 case HCI_EV_KEYPRESS_NOTIFY:
3806 hci_keypress_notify_evt(hdev, skb);
3807 break;
3808
Marcel Holtmann04936842008-07-14 20:13:48 +02003809 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3810 hci_simple_pair_complete_evt(hdev, skb);
3811 break;
3812
Marcel Holtmann41a96212008-07-14 20:13:48 +02003813 case HCI_EV_REMOTE_HOST_FEATURES:
3814 hci_remote_host_features_evt(hdev, skb);
3815 break;
3816
Ville Tervofcd89c02011-02-10 22:38:47 -03003817 case HCI_EV_LE_META:
3818 hci_le_meta_evt(hdev, skb);
3819 break;
3820
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003821 case HCI_EV_CHANNEL_SELECTED:
3822 hci_chan_selected_evt(hdev, skb);
3823 break;
3824
Szymon Janc2763eda2011-03-22 13:12:22 +01003825 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3826 hci_remote_oob_data_request_evt(hdev, skb);
3827 break;
3828
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003829 case HCI_EV_PHY_LINK_COMPLETE:
3830 hci_phy_link_complete_evt(hdev, skb);
3831 break;
3832
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003833 case HCI_EV_LOGICAL_LINK_COMPLETE:
3834 hci_loglink_complete_evt(hdev, skb);
3835 break;
3836
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003837 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3838 hci_disconn_loglink_complete_evt(hdev, skb);
3839 break;
3840
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003841 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3842 hci_disconn_phylink_complete_evt(hdev, skb);
3843 break;
3844
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003845 case HCI_EV_NUM_COMP_BLOCKS:
3846 hci_num_comp_blocks_evt(hdev, skb);
3847 break;
3848
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003849 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003850 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003851 break;
3852 }
3853
3854 kfree_skb(skb);
3855 hdev->stat.evt_rx++;
3856}