blob: e3d7151e808edb88ce5495e1d448ae9cc1006426 [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 Holtmanneac83dc2014-01-10 02:07:23 -0800464static void hci_cc_write_sc_support(struct hci_dev *hdev, struct sk_buff *skb)
465{
466 u8 status = *((u8 *) skb->data);
467 struct hci_cp_write_sc_support *sent;
468
469 BT_DBG("%s status 0x%2.2x", hdev->name, status);
470
471 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SC_SUPPORT);
472 if (!sent)
473 return;
474
475 if (!status) {
476 if (sent->support)
477 hdev->features[1][0] |= LMP_HOST_SC;
478 else
479 hdev->features[1][0] &= ~LMP_HOST_SC;
480 }
481
482 if (test_bit(HCI_MGMT, &hdev->dev_flags))
483 mgmt_sc_enable_complete(hdev, sent->support, status);
484 else if (!status) {
485 if (sent->support)
486 set_bit(HCI_SC_ENABLED, &hdev->dev_flags);
487 else
488 clear_bit(HCI_SC_ENABLED, &hdev->dev_flags);
489 }
490}
491
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200492static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
493{
494 struct hci_rp_read_local_version *rp = (void *) skb->data;
495
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300496 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200497
498 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200499 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200500
Marcel Holtmann0d5551f2013-10-18 12:04:50 -0700501 if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
502 hdev->hci_ver = rp->hci_ver;
503 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
504 hdev->lmp_ver = rp->lmp_ver;
505 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
506 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
507 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200508}
509
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300510static void hci_cc_read_local_commands(struct hci_dev *hdev,
511 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200512{
513 struct hci_rp_read_local_commands *rp = (void *) skb->data;
514
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300515 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200516
Marcel Holtmann6a070e62013-10-31 04:54:33 -0700517 if (rp->status)
518 return;
519
520 if (test_bit(HCI_SETUP, &hdev->dev_flags))
Johan Hedberg2177bab2013-03-05 20:37:43 +0200521 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200522}
523
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300524static void hci_cc_read_local_features(struct hci_dev *hdev,
525 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200526{
527 struct hci_rp_read_local_features *rp = (void *) skb->data;
528
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300529 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200530
531 if (rp->status)
532 return;
533
534 memcpy(hdev->features, rp->features, 8);
535
536 /* Adjust default settings according to features
537 * supported by device. */
538
Johan Hedbergcad718e2013-04-17 15:00:51 +0300539 if (hdev->features[0][0] & LMP_3SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200540 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
541
Johan Hedbergcad718e2013-04-17 15:00:51 +0300542 if (hdev->features[0][0] & LMP_5SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200543 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
544
Johan Hedbergcad718e2013-04-17 15:00:51 +0300545 if (hdev->features[0][1] & LMP_HV2) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200546 hdev->pkt_type |= (HCI_HV2);
547 hdev->esco_type |= (ESCO_HV2);
548 }
549
Johan Hedbergcad718e2013-04-17 15:00:51 +0300550 if (hdev->features[0][1] & LMP_HV3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200551 hdev->pkt_type |= (HCI_HV3);
552 hdev->esco_type |= (ESCO_HV3);
553 }
554
Andre Guedes45db810f2012-07-24 15:03:49 -0300555 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200556 hdev->esco_type |= (ESCO_EV3);
557
Johan Hedbergcad718e2013-04-17 15:00:51 +0300558 if (hdev->features[0][4] & LMP_EV4)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200559 hdev->esco_type |= (ESCO_EV4);
560
Johan Hedbergcad718e2013-04-17 15:00:51 +0300561 if (hdev->features[0][4] & LMP_EV5)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200562 hdev->esco_type |= (ESCO_EV5);
563
Johan Hedbergcad718e2013-04-17 15:00:51 +0300564 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100565 hdev->esco_type |= (ESCO_2EV3);
566
Johan Hedbergcad718e2013-04-17 15:00:51 +0300567 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100568 hdev->esco_type |= (ESCO_3EV3);
569
Johan Hedbergcad718e2013-04-17 15:00:51 +0300570 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100571 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200572}
573
Andre Guedes971e3a42011-06-30 19:20:52 -0300574static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300575 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300576{
577 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
578
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300579 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300580
581 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200582 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300583
Marcel Holtmann57af75a2013-10-18 12:04:47 -0700584 if (hdev->max_page < rp->max_page)
585 hdev->max_page = rp->max_page;
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300586
Johan Hedbergcad718e2013-04-17 15:00:51 +0300587 if (rp->page < HCI_MAX_PAGES)
588 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300589}
590
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200591static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300592 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200593{
594 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
595
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300596 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200597
Johan Hedberg42c6b122013-03-05 20:37:49 +0200598 if (!rp->status)
599 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200600}
601
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200602static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
603{
604 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
605
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300606 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200607
608 if (rp->status)
609 return;
610
611 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
612 hdev->sco_mtu = rp->sco_mtu;
613 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
614 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
615
616 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
617 hdev->sco_mtu = 64;
618 hdev->sco_pkts = 8;
619 }
620
621 hdev->acl_cnt = hdev->acl_pkts;
622 hdev->sco_cnt = hdev->sco_pkts;
623
Gustavo Padovan807deac2012-05-17 00:36:24 -0300624 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
625 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200626}
627
628static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
629{
630 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
631
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300632 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200633
634 if (!rp->status)
635 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200636}
637
Johan Hedbergf332ec62013-03-15 17:07:11 -0500638static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
639 struct sk_buff *skb)
640{
641 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
642
643 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
644
645 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
646 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
647 hdev->page_scan_window = __le16_to_cpu(rp->window);
648 }
649}
650
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500651static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
652 struct sk_buff *skb)
653{
654 u8 status = *((u8 *) skb->data);
655 struct hci_cp_write_page_scan_activity *sent;
656
657 BT_DBG("%s status 0x%2.2x", hdev->name, status);
658
659 if (status)
660 return;
661
662 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
663 if (!sent)
664 return;
665
666 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
667 hdev->page_scan_window = __le16_to_cpu(sent->window);
668}
669
Johan Hedbergf332ec62013-03-15 17:07:11 -0500670static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
671 struct sk_buff *skb)
672{
673 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
674
675 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
676
677 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
678 hdev->page_scan_type = rp->type;
679}
680
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500681static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
682 struct sk_buff *skb)
683{
684 u8 status = *((u8 *) skb->data);
685 u8 *type;
686
687 BT_DBG("%s status 0x%2.2x", hdev->name, status);
688
689 if (status)
690 return;
691
692 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
693 if (type)
694 hdev->page_scan_type = *type;
695}
696
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200697static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300698 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200699{
700 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
701
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300702 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200703
704 if (rp->status)
705 return;
706
707 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
708 hdev->block_len = __le16_to_cpu(rp->block_len);
709 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
710
711 hdev->block_cnt = hdev->num_blocks;
712
713 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300714 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200715}
716
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300717static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300718 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300719{
720 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
721
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300722 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300723
724 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300725 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300726
727 hdev->amp_status = rp->amp_status;
728 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
729 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
730 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
731 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
732 hdev->amp_type = rp->amp_type;
733 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
734 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
735 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
736 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
737
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300738a2mp_rsp:
739 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300740}
741
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300742static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
743 struct sk_buff *skb)
744{
745 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
746 struct amp_assoc *assoc = &hdev->loc_assoc;
747 size_t rem_len, frag_len;
748
749 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
750
751 if (rp->status)
752 goto a2mp_rsp;
753
754 frag_len = skb->len - sizeof(*rp);
755 rem_len = __le16_to_cpu(rp->rem_len);
756
757 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300758 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300759
760 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
761 assoc->offset += frag_len;
762
763 /* Read other fragments */
764 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
765
766 return;
767 }
768
769 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
770 assoc->len = assoc->offset + rem_len;
771 assoc->offset = 0;
772
773a2mp_rsp:
774 /* Send A2MP Rsp when all fragments are received */
775 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300776 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300777}
778
Johan Hedbergd5859e22011-01-25 01:19:58 +0200779static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300780 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200781{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700782 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200783
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300784 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200785
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700786 if (!rp->status)
787 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200788}
789
Johan Hedberg980e1a52011-01-22 06:10:07 +0200790static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
791{
792 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
793 struct hci_cp_pin_code_reply *cp;
794 struct hci_conn *conn;
795
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300796 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200797
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200798 hci_dev_lock(hdev);
799
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200800 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200801 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200802
Mikel Astizfa1bd912012-08-09 09:52:29 +0200803 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200804 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200805
806 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
807 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200808 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200809
810 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
811 if (conn)
812 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200813
814unlock:
815 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200816}
817
818static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
819{
820 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
821
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300822 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200823
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200824 hci_dev_lock(hdev);
825
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200826 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200827 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300828 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200829
830 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200831}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200832
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300833static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
834 struct sk_buff *skb)
835{
836 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
837
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300838 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300839
840 if (rp->status)
841 return;
842
843 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
844 hdev->le_pkts = rp->le_max_pkt;
845
846 hdev->le_cnt = hdev->le_pkts;
847
848 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300849}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200850
Johan Hedberg60e77322013-01-22 14:01:59 +0200851static void hci_cc_le_read_local_features(struct hci_dev *hdev,
852 struct sk_buff *skb)
853{
854 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
855
856 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
857
858 if (!rp->status)
859 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200860}
861
Johan Hedberg8fa19092012-10-19 20:57:49 +0300862static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
863 struct sk_buff *skb)
864{
865 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
866
867 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
868
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500869 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300870 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300871}
872
Johan Hedberga5c29682011-02-19 12:05:57 -0300873static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
874{
875 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
876
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300877 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300878
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200879 hci_dev_lock(hdev);
880
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200881 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300882 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
883 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200884
885 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300886}
887
888static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300889 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300890{
891 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
892
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300893 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300894
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200895 hci_dev_lock(hdev);
896
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200897 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200898 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300899 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200900
901 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300902}
903
Brian Gix1143d452011-11-23 08:28:34 -0800904static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
905{
906 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
907
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300908 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800909
910 hci_dev_lock(hdev);
911
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200912 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200913 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300914 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800915
916 hci_dev_unlock(hdev);
917}
918
919static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300920 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800921{
922 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
923
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300924 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800925
926 hci_dev_lock(hdev);
927
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200928 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800929 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300930 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800931
932 hci_dev_unlock(hdev);
933}
934
Marcel Holtmann4d2d2792014-01-10 02:07:26 -0800935static void hci_cc_read_local_oob_data(struct hci_dev *hdev,
936 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100937{
938 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
939
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300940 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100941
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200942 hci_dev_lock(hdev);
Marcel Holtmann4d2d2792014-01-10 02:07:26 -0800943 mgmt_read_local_oob_data_complete(hdev, rp->hash, rp->randomizer,
944 NULL, NULL, rp->status);
945 hci_dev_unlock(hdev);
946}
947
948static void hci_cc_read_local_oob_ext_data(struct hci_dev *hdev,
949 struct sk_buff *skb)
950{
951 struct hci_rp_read_local_oob_ext_data *rp = (void *) skb->data;
952
953 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
954
955 hci_dev_lock(hdev);
956 mgmt_read_local_oob_data_complete(hdev, rp->hash192, rp->randomizer192,
957 rp->hash256, rp->randomizer256,
958 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200959 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100960}
961
Marcel Holtmann7a4cd512014-02-19 19:52:13 -0800962
963static void hci_cc_le_set_random_addr(struct hci_dev *hdev, struct sk_buff *skb)
964{
965 __u8 status = *((__u8 *) skb->data);
966 bdaddr_t *sent;
967
968 BT_DBG("%s status 0x%2.2x", hdev->name, status);
969
970 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_RANDOM_ADDR);
971 if (!sent)
972 return;
973
974 hci_dev_lock(hdev);
975
976 if (!status)
977 bacpy(&hdev->random_addr, sent);
978
979 hci_dev_unlock(hdev);
980}
981
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100982static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
983{
984 __u8 *sent, status = *((__u8 *) skb->data);
985
986 BT_DBG("%s status 0x%2.2x", hdev->name, status);
987
988 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
989 if (!sent)
990 return;
991
992 hci_dev_lock(hdev);
993
Johan Hedberg778b2352014-02-24 14:52:17 +0200994 if (!status)
995 mgmt_advertising(hdev, *sent);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100996
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500997 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100998}
999
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001000static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001001 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001002{
1003 struct hci_cp_le_set_scan_enable *cp;
1004 __u8 status = *((__u8 *) skb->data);
1005
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001006 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001007
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001008 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1009 if (!cp)
1010 return;
1011
Andre Guedes3fd319b2013-04-30 15:29:36 -03001012 if (status)
1013 return;
1014
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001015 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -03001016 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -03001017 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001018 break;
1019
Andre Guedes76a388b2013-04-04 20:21:02 -03001020 case LE_SCAN_DISABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -03001021 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001022 break;
1023
1024 default:
1025 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1026 break;
Andre Guedes35815082011-05-26 16:23:53 -03001027 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001028}
1029
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001030static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
1031 struct sk_buff *skb)
1032{
1033 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
1034
1035 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
1036
1037 if (!rp->status)
1038 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +02001039}
1040
Marcel Holtmann0f36b582014-02-27 20:37:31 -08001041static void hci_cc_le_clear_white_list(struct hci_dev *hdev,
1042 struct sk_buff *skb)
1043{
1044 __u8 status = *((__u8 *) skb->data);
1045
1046 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1047
1048 if (!status)
1049 hci_white_list_clear(hdev);
1050}
1051
1052static void hci_cc_le_add_to_white_list(struct hci_dev *hdev,
1053 struct sk_buff *skb)
1054{
1055 struct hci_cp_le_add_to_white_list *sent;
1056 __u8 status = *((__u8 *) skb->data);
1057
1058 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1059
1060 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_WHITE_LIST);
1061 if (!sent)
1062 return;
1063
1064 if (!status)
1065 hci_white_list_add(hdev, &sent->bdaddr, sent->bdaddr_type);
1066}
1067
1068static void hci_cc_le_del_from_white_list(struct hci_dev *hdev,
1069 struct sk_buff *skb)
1070{
1071 struct hci_cp_le_del_from_white_list *sent;
1072 __u8 status = *((__u8 *) skb->data);
1073
1074 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1075
1076 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_WHITE_LIST);
1077 if (!sent)
1078 return;
1079
1080 if (!status)
1081 hci_white_list_del(hdev, &sent->bdaddr, sent->bdaddr_type);
1082}
1083
Johan Hedberg9b008c02013-01-22 14:02:01 +02001084static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
1085 struct sk_buff *skb)
1086{
1087 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
1088
1089 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1090
1091 if (!rp->status)
1092 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +02001093}
1094
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001095static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1096 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001097{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001098 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001099 __u8 status = *((__u8 *) skb->data);
1100
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001101 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001102
Johan Hedberg06199cf2012-02-22 16:37:11 +02001103 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001104 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001105 return;
1106
Johan Hedberg8f984df2012-02-28 01:07:22 +02001107 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001108 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001109 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001110 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1111 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001112 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001113 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001114 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001115 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001116
1117 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001118 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001119 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001120 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001121 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001122}
1123
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02001124static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
1125{
1126 struct hci_cp_le_set_adv_param *cp;
1127 u8 status = *((u8 *) skb->data);
1128
1129 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1130
1131 if (status)
1132 return;
1133
1134 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_PARAM);
1135 if (!cp)
1136 return;
1137
1138 hci_dev_lock(hdev);
1139 hdev->adv_addr_type = cp->own_address_type;
1140 hci_dev_unlock(hdev);
1141}
1142
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001143static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1144 struct sk_buff *skb)
1145{
1146 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1147
1148 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1149 hdev->name, rp->status, rp->phy_handle);
1150
1151 if (rp->status)
1152 return;
1153
1154 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1155}
1156
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001157static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001158{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001159 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001160
1161 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001162 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001163 return;
1164 }
1165
Andre Guedes89352e72011-11-04 14:16:53 -03001166 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001167}
1168
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001169static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001171 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001174 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001175
1176 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177 if (!cp)
1178 return;
1179
1180 hci_dev_lock(hdev);
1181
1182 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1183
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001184 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185
1186 if (status) {
1187 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001188 if (status != 0x0c || conn->attempt > 2) {
1189 conn->state = BT_CLOSED;
1190 hci_proto_connect_cfm(conn, status);
1191 hci_conn_del(conn);
1192 } else
1193 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194 }
1195 } else {
1196 if (!conn) {
1197 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1198 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001199 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200 conn->link_mode |= HCI_LM_MASTER;
1201 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001202 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 }
1204 }
1205
1206 hci_dev_unlock(hdev);
1207}
1208
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001209static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001211 struct hci_cp_add_sco *cp;
1212 struct hci_conn *acl, *sco;
1213 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001215 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001216
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001217 if (!status)
1218 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001220 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1221 if (!cp)
1222 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001224 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001226 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001227
1228 hci_dev_lock(hdev);
1229
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001230 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001231 if (acl) {
1232 sco = acl->link;
1233 if (sco) {
1234 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001235
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001236 hci_proto_connect_cfm(sco, status);
1237 hci_conn_del(sco);
1238 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001239 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001240
1241 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242}
1243
Marcel Holtmannf8558552008-07-14 20:13:49 +02001244static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1245{
1246 struct hci_cp_auth_requested *cp;
1247 struct hci_conn *conn;
1248
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001249 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001250
1251 if (!status)
1252 return;
1253
1254 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1255 if (!cp)
1256 return;
1257
1258 hci_dev_lock(hdev);
1259
1260 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1261 if (conn) {
1262 if (conn->state == BT_CONFIG) {
1263 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001264 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001265 }
1266 }
1267
1268 hci_dev_unlock(hdev);
1269}
1270
1271static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1272{
1273 struct hci_cp_set_conn_encrypt *cp;
1274 struct hci_conn *conn;
1275
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001276 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001277
1278 if (!status)
1279 return;
1280
1281 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1282 if (!cp)
1283 return;
1284
1285 hci_dev_lock(hdev);
1286
1287 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1288 if (conn) {
1289 if (conn->state == BT_CONFIG) {
1290 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001291 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001292 }
1293 }
1294
1295 hci_dev_unlock(hdev);
1296}
1297
Johan Hedberg127178d2010-11-18 22:22:29 +02001298static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001299 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001300{
Johan Hedberg392599b2010-11-18 22:22:28 +02001301 if (conn->state != BT_CONFIG || !conn->out)
1302 return 0;
1303
Johan Hedberg765c2a92011-01-19 12:06:52 +05301304 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001305 return 0;
1306
1307 /* Only request authentication for SSP connections or non-SSP
Johan Hedberg264b8b42014-01-08 16:40:39 +02001308 * devices with sec_level MEDIUM or HIGH or if MITM protection
1309 * is requested.
1310 */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001311 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
Johan Hedberg264b8b42014-01-08 16:40:39 +02001312 conn->pending_sec_level != BT_SECURITY_HIGH &&
1313 conn->pending_sec_level != BT_SECURITY_MEDIUM)
Johan Hedberg392599b2010-11-18 22:22:28 +02001314 return 0;
1315
Johan Hedberg392599b2010-11-18 22:22:28 +02001316 return 1;
1317}
1318
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001319static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001320 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001321{
1322 struct hci_cp_remote_name_req cp;
1323
1324 memset(&cp, 0, sizeof(cp));
1325
1326 bacpy(&cp.bdaddr, &e->data.bdaddr);
1327 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1328 cp.pscan_mode = e->data.pscan_mode;
1329 cp.clock_offset = e->data.clock_offset;
1330
1331 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1332}
1333
Johan Hedbergb644ba32012-01-17 21:48:47 +02001334static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001335{
1336 struct discovery_state *discov = &hdev->discovery;
1337 struct inquiry_entry *e;
1338
Johan Hedbergb644ba32012-01-17 21:48:47 +02001339 if (list_empty(&discov->resolve))
1340 return false;
1341
1342 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001343 if (!e)
1344 return false;
1345
Johan Hedbergb644ba32012-01-17 21:48:47 +02001346 if (hci_resolve_name(hdev, e) == 0) {
1347 e->name_state = NAME_PENDING;
1348 return true;
1349 }
1350
1351 return false;
1352}
1353
1354static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001355 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001356{
1357 struct discovery_state *discov = &hdev->discovery;
1358 struct inquiry_entry *e;
1359
1360 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001361 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1362 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001363
1364 if (discov->state == DISCOVERY_STOPPED)
1365 return;
1366
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001367 if (discov->state == DISCOVERY_STOPPING)
1368 goto discov_complete;
1369
1370 if (discov->state != DISCOVERY_RESOLVING)
1371 return;
1372
1373 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001374 /* If the device was not found in a list of found devices names of which
1375 * are pending. there is no need to continue resolving a next name as it
1376 * will be done upon receiving another Remote Name Request Complete
1377 * Event */
1378 if (!e)
1379 return;
1380
1381 list_del(&e->list);
1382 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001383 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001384 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1385 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001386 } else {
1387 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001388 }
1389
Johan Hedbergb644ba32012-01-17 21:48:47 +02001390 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001391 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001392
1393discov_complete:
1394 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1395}
1396
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001397static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1398{
Johan Hedberg127178d2010-11-18 22:22:29 +02001399 struct hci_cp_remote_name_req *cp;
1400 struct hci_conn *conn;
1401
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001402 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001403
1404 /* If successful wait for the name req complete event before
1405 * checking for the need to do authentication */
1406 if (!status)
1407 return;
1408
1409 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1410 if (!cp)
1411 return;
1412
1413 hci_dev_lock(hdev);
1414
1415 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001416
1417 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1418 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1419
Johan Hedberg79c6c702011-04-28 11:28:55 -07001420 if (!conn)
1421 goto unlock;
1422
1423 if (!hci_outgoing_auth_needed(hdev, conn))
1424 goto unlock;
1425
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001426 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02001427 struct hci_cp_auth_requested auth_cp;
1428
1429 auth_cp.handle = __cpu_to_le16(conn->handle);
1430 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1431 sizeof(auth_cp), &auth_cp);
Johan Hedberg127178d2010-11-18 22:22:29 +02001432 }
1433
Johan Hedberg79c6c702011-04-28 11:28:55 -07001434unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001435 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001436}
1437
Marcel Holtmann769be972008-07-14 20:13:49 +02001438static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1439{
1440 struct hci_cp_read_remote_features *cp;
1441 struct hci_conn *conn;
1442
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001443 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001444
1445 if (!status)
1446 return;
1447
1448 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1449 if (!cp)
1450 return;
1451
1452 hci_dev_lock(hdev);
1453
1454 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1455 if (conn) {
1456 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001457 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001458 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001459 }
1460 }
1461
1462 hci_dev_unlock(hdev);
1463}
1464
1465static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1466{
1467 struct hci_cp_read_remote_ext_features *cp;
1468 struct hci_conn *conn;
1469
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001470 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001471
1472 if (!status)
1473 return;
1474
1475 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1476 if (!cp)
1477 return;
1478
1479 hci_dev_lock(hdev);
1480
1481 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1482 if (conn) {
1483 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001484 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001485 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001486 }
1487 }
1488
1489 hci_dev_unlock(hdev);
1490}
1491
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001492static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1493{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001494 struct hci_cp_setup_sync_conn *cp;
1495 struct hci_conn *acl, *sco;
1496 __u16 handle;
1497
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001498 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001499
1500 if (!status)
1501 return;
1502
1503 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1504 if (!cp)
1505 return;
1506
1507 handle = __le16_to_cpu(cp->handle);
1508
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001509 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001510
1511 hci_dev_lock(hdev);
1512
1513 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001514 if (acl) {
1515 sco = acl->link;
1516 if (sco) {
1517 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001518
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001519 hci_proto_connect_cfm(sco, status);
1520 hci_conn_del(sco);
1521 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001522 }
1523
1524 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001525}
1526
1527static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1528{
1529 struct hci_cp_sniff_mode *cp;
1530 struct hci_conn *conn;
1531
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001532 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001533
1534 if (!status)
1535 return;
1536
1537 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1538 if (!cp)
1539 return;
1540
1541 hci_dev_lock(hdev);
1542
1543 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001544 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001545 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001546
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001547 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001548 hci_sco_setup(conn, status);
1549 }
1550
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001551 hci_dev_unlock(hdev);
1552}
1553
1554static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1555{
1556 struct hci_cp_exit_sniff_mode *cp;
1557 struct hci_conn *conn;
1558
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001559 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001560
1561 if (!status)
1562 return;
1563
1564 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1565 if (!cp)
1566 return;
1567
1568 hci_dev_lock(hdev);
1569
1570 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001571 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001572 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001573
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001574 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001575 hci_sco_setup(conn, status);
1576 }
1577
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001578 hci_dev_unlock(hdev);
1579}
1580
Johan Hedberg88c3df12012-02-09 14:27:38 +02001581static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1582{
1583 struct hci_cp_disconnect *cp;
1584 struct hci_conn *conn;
1585
1586 if (!status)
1587 return;
1588
1589 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1590 if (!cp)
1591 return;
1592
1593 hci_dev_lock(hdev);
1594
1595 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1596 if (conn)
1597 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001598 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001599
1600 hci_dev_unlock(hdev);
1601}
1602
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001603static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1604{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001605 struct hci_cp_create_phy_link *cp;
1606
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001607 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001608
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001609 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1610 if (!cp)
1611 return;
1612
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001613 hci_dev_lock(hdev);
1614
1615 if (status) {
1616 struct hci_conn *hcon;
1617
1618 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1619 if (hcon)
1620 hci_conn_del(hcon);
1621 } else {
1622 amp_write_remote_assoc(hdev, cp->phy_handle);
1623 }
1624
1625 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001626}
1627
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001628static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1629{
1630 struct hci_cp_accept_phy_link *cp;
1631
1632 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1633
1634 if (status)
1635 return;
1636
1637 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1638 if (!cp)
1639 return;
1640
1641 amp_write_remote_assoc(hdev, cp->phy_handle);
1642}
1643
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001644static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001645{
1646 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001647 struct discovery_state *discov = &hdev->discovery;
1648 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001649
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001650 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001651
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001652 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001653
1654 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1655 return;
1656
Andre Guedes3e13fa12013-03-27 20:04:56 -03001657 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1658 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1659
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001660 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001661 return;
1662
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001663 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001664
Andre Guedes343f9352012-02-17 20:39:37 -03001665 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001666 goto unlock;
1667
1668 if (list_empty(&discov->resolve)) {
1669 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1670 goto unlock;
1671 }
1672
1673 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1674 if (e && hci_resolve_name(hdev, e) == 0) {
1675 e->name_state = NAME_PENDING;
1676 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1677 } else {
1678 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1679 }
1680
1681unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001682 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001683}
1684
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001685static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001687 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001688 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 int num_rsp = *((__u8 *) skb->data);
1690
1691 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1692
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001693 if (!num_rsp)
1694 return;
1695
Andre Guedes1519cc12012-03-21 00:03:38 -03001696 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1697 return;
1698
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001700
Johan Hedberge17acd42011-03-30 23:57:16 +03001701 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001702 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001703
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 bacpy(&data.bdaddr, &info->bdaddr);
1705 data.pscan_rep_mode = info->pscan_rep_mode;
1706 data.pscan_period_mode = info->pscan_period_mode;
1707 data.pscan_mode = info->pscan_mode;
1708 memcpy(data.dev_class, info->dev_class, 3);
1709 data.clock_offset = info->clock_offset;
1710 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001711 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001712
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001713 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001714 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001715 info->dev_class, 0, !name_known, ssp, NULL,
1716 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001718
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 hci_dev_unlock(hdev);
1720}
1721
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001722static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001724 struct hci_ev_conn_complete *ev = (void *) skb->data;
1725 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001727 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001728
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001730
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001731 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001732 if (!conn) {
1733 if (ev->link_type != SCO_LINK)
1734 goto unlock;
1735
1736 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1737 if (!conn)
1738 goto unlock;
1739
1740 conn->type = SCO_LINK;
1741 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001742
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001743 if (!ev->status) {
1744 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001745
1746 if (conn->type == ACL_LINK) {
1747 conn->state = BT_CONFIG;
1748 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001749
1750 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1751 !hci_find_link_key(hdev, &ev->bdaddr))
1752 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1753 else
1754 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001755 } else
1756 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001757
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001758 hci_conn_add_sysfs(conn);
1759
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001760 if (test_bit(HCI_AUTH, &hdev->flags))
1761 conn->link_mode |= HCI_LM_AUTH;
1762
1763 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1764 conn->link_mode |= HCI_LM_ENCRYPT;
1765
1766 /* Get remote features */
1767 if (conn->type == ACL_LINK) {
1768 struct hci_cp_read_remote_features cp;
1769 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001770 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001771 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001772 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001773
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001774 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001775 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001776 struct hci_cp_change_conn_ptype cp;
1777 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001778 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001779 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1780 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001781 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001782 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001783 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001784 if (conn->type == ACL_LINK)
Marcel Holtmann64c7b772014-02-18 14:22:20 -08001785 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001786 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001787 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001788
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001789 if (conn->type == ACL_LINK)
1790 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001791
Marcel Holtmann769be972008-07-14 20:13:49 +02001792 if (ev->status) {
1793 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001794 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001795 } else if (ev->link_type != ACL_LINK)
1796 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001797
1798unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001800
1801 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802}
1803
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001804static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001806 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001808 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001810 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001811 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001813 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1814 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815
Szymon Janc138d22e2011-02-17 16:44:23 +01001816 if ((mask & HCI_LM_ACCEPT) &&
Marcel Holtmannb9ee0a72013-10-17 17:24:13 -07001817 !hci_blacklist_lookup(hdev, &ev->bdaddr, BDADDR_BREDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001819 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821
1822 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001823
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001824 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1825 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001826 memcpy(ie->data.dev_class, ev->dev_class, 3);
1827
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001828 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1829 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001831 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1832 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001833 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 hci_dev_unlock(hdev);
1835 return;
1836 }
1837 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001838
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001840
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 hci_dev_unlock(hdev);
1842
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001843 if (ev->link_type == ACL_LINK ||
1844 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001845 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001846 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001848 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001850 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1851 cp.role = 0x00; /* Become master */
1852 else
1853 cp.role = 0x01; /* Remain slave */
1854
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001855 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1856 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001857 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001858 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001859 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001860
1861 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001862 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001863
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001864 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1865 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1866 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001867 cp.content_format = cpu_to_le16(hdev->voice_setting);
1868 cp.retrans_effort = 0xff;
1869
1870 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001871 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001872 } else {
1873 conn->state = BT_CONNECT2;
1874 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001875 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876 } else {
1877 /* Connection rejected */
1878 struct hci_cp_reject_conn_req cp;
1879
1880 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001881 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001882 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883 }
1884}
1885
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001886static u8 hci_to_mgmt_reason(u8 err)
1887{
1888 switch (err) {
1889 case HCI_ERROR_CONNECTION_TIMEOUT:
1890 return MGMT_DEV_DISCONN_TIMEOUT;
1891 case HCI_ERROR_REMOTE_USER_TERM:
1892 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1893 case HCI_ERROR_REMOTE_POWER_OFF:
1894 return MGMT_DEV_DISCONN_REMOTE;
1895 case HCI_ERROR_LOCAL_HOST_TERM:
1896 return MGMT_DEV_DISCONN_LOCAL_HOST;
1897 default:
1898 return MGMT_DEV_DISCONN_UNKNOWN;
1899 }
1900}
1901
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001902static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001904 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Andre Guedesabf54a52013-11-07 17:36:09 -03001905 u8 reason = hci_to_mgmt_reason(ev->reason);
Andre Guedes9fcb18e2014-02-26 20:21:48 -03001906 struct hci_conn_params *params;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001907 struct hci_conn *conn;
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02001908 bool mgmt_connected;
Andre Guedes38462202013-11-07 17:36:10 -03001909 u8 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001911 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913 hci_dev_lock(hdev);
1914
Marcel Holtmann04837f62006-07-03 10:02:33 +02001915 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001916 if (!conn)
1917 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001918
Andre Guedesabf54a52013-11-07 17:36:09 -03001919 if (ev->status) {
1920 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1921 conn->dst_type, ev->status);
1922 goto unlock;
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001923 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001924
Andre Guedes38462202013-11-07 17:36:10 -03001925 conn->state = BT_CLOSED;
1926
Johan Hedberg12d4a3b2014-02-24 14:52:18 +02001927 mgmt_connected = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
1928 mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type,
1929 reason, mgmt_connected);
Andre Guedesabf54a52013-11-07 17:36:09 -03001930
Andre Guedes38462202013-11-07 17:36:10 -03001931 if (conn->type == ACL_LINK && conn->flush_key)
1932 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg22102462013-10-05 12:01:06 +02001933
Andre Guedes9fcb18e2014-02-26 20:21:48 -03001934 params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
1935 if (params) {
1936 switch (params->auto_connect) {
1937 case HCI_AUTO_CONN_LINK_LOSS:
1938 if (ev->reason != HCI_ERROR_CONNECTION_TIMEOUT)
1939 break;
1940 /* Fall through */
1941
1942 case HCI_AUTO_CONN_ALWAYS:
1943 hci_pend_le_conn_add(hdev, &conn->dst, conn->dst_type);
1944 break;
1945
1946 default:
1947 break;
1948 }
1949 }
1950
Andre Guedes38462202013-11-07 17:36:10 -03001951 type = conn->type;
Johan Hedberg22102462013-10-05 12:01:06 +02001952
Andre Guedes38462202013-11-07 17:36:10 -03001953 hci_proto_disconn_cfm(conn, ev->reason);
1954 hci_conn_del(conn);
1955
1956 /* Re-enable advertising if necessary, since it might
1957 * have been disabled by the connection. From the
1958 * HCI_LE_Set_Advertise_Enable command description in
1959 * the core specification (v4.0):
1960 * "The Controller shall continue advertising until the Host
1961 * issues an LE_Set_Advertise_Enable command with
1962 * Advertising_Enable set to 0x00 (Advertising is disabled)
1963 * or until a connection is created or until the Advertising
1964 * is timed out due to Directed Advertising."
1965 */
1966 if (type == LE_LINK)
1967 mgmt_reenable_advertising(hdev);
Johan Hedbergf7520542011-01-20 12:34:39 +02001968
1969unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001970 hci_dev_unlock(hdev);
1971}
1972
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001973static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001974{
1975 struct hci_ev_auth_complete *ev = (void *) skb->data;
1976 struct hci_conn *conn;
1977
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001978 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001979
1980 hci_dev_lock(hdev);
1981
1982 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001983 if (!conn)
1984 goto unlock;
1985
1986 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001987 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001988 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001989 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001990 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001991 conn->link_mode |= HCI_LM_AUTH;
1992 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001993 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001994 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001995 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001996 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001997 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001998
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001999 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
2000 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002001
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002002 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002003 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002004 struct hci_cp_set_conn_encrypt cp;
2005 cp.handle = ev->handle;
2006 cp.encrypt = 0x01;
2007 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002008 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002009 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002010 conn->state = BT_CONNECTED;
2011 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002012 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002013 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002014 } else {
2015 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002016
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002017 hci_conn_hold(conn);
2018 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002019 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002020 }
2021
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002022 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002023 if (!ev->status) {
2024 struct hci_cp_set_conn_encrypt cp;
2025 cp.handle = ev->handle;
2026 cp.encrypt = 0x01;
2027 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002028 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002029 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002030 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002031 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002032 }
2033 }
2034
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002035unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002036 hci_dev_unlock(hdev);
2037}
2038
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002039static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002040{
Johan Hedberg127178d2010-11-18 22:22:29 +02002041 struct hci_ev_remote_name *ev = (void *) skb->data;
2042 struct hci_conn *conn;
2043
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002044 BT_DBG("%s", hdev->name);
2045
2046 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02002047
2048 hci_dev_lock(hdev);
2049
2050 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002051
2052 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2053 goto check_auth;
2054
2055 if (ev->status == 0)
2056 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002057 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002058 else
2059 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2060
2061check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002062 if (!conn)
2063 goto unlock;
2064
2065 if (!hci_outgoing_auth_needed(hdev, conn))
2066 goto unlock;
2067
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002068 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002069 struct hci_cp_auth_requested cp;
2070 cp.handle = __cpu_to_le16(conn->handle);
2071 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2072 }
2073
Johan Hedberg79c6c702011-04-28 11:28:55 -07002074unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002075 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002076}
2077
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002078static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002079{
2080 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2081 struct hci_conn *conn;
2082
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002083 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002084
2085 hci_dev_lock(hdev);
2086
2087 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002088 if (!conn)
2089 goto unlock;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002090
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002091 if (!ev->status) {
2092 if (ev->encrypt) {
2093 /* Encryption implies authentication */
2094 conn->link_mode |= HCI_LM_AUTH;
2095 conn->link_mode |= HCI_LM_ENCRYPT;
2096 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002097
Marcel Holtmann914a6ff2014-02-01 11:52:02 -08002098 /* P-256 authentication key implies FIPS */
2099 if (conn->key_type == HCI_LK_AUTH_COMBINATION_P256)
2100 conn->link_mode |= HCI_LM_FIPS;
2101
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002102 if ((conn->type == ACL_LINK && ev->encrypt == 0x02) ||
2103 conn->type == LE_LINK)
2104 set_bit(HCI_CONN_AES_CCM, &conn->flags);
2105 } else {
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002106 conn->link_mode &= ~HCI_LM_ENCRYPT;
Marcel Holtmannabf76ba2014-01-31 16:24:28 -08002107 clear_bit(HCI_CONN_AES_CCM, &conn->flags);
2108 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002109 }
2110
Marcel Holtmanndc8357c2014-01-31 16:24:27 -08002111 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
2112
2113 if (ev->status && conn->state == BT_CONNECTED) {
2114 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
2115 hci_conn_drop(conn);
2116 goto unlock;
2117 }
2118
2119 if (conn->state == BT_CONFIG) {
2120 if (!ev->status)
2121 conn->state = BT_CONNECTED;
2122
2123 hci_proto_connect_cfm(conn, ev->status);
2124 hci_conn_drop(conn);
2125 } else
2126 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
2127
Gustavo Padovana7d77232012-05-13 03:20:07 -03002128unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002129 hci_dev_unlock(hdev);
2130}
2131
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002132static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2133 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002134{
2135 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2136 struct hci_conn *conn;
2137
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002138 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002139
2140 hci_dev_lock(hdev);
2141
2142 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2143 if (conn) {
2144 if (!ev->status)
2145 conn->link_mode |= HCI_LM_SECURE;
2146
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002147 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002148
2149 hci_key_change_cfm(conn, ev->status);
2150 }
2151
2152 hci_dev_unlock(hdev);
2153}
2154
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002155static void hci_remote_features_evt(struct hci_dev *hdev,
2156 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002157{
2158 struct hci_ev_remote_features *ev = (void *) skb->data;
2159 struct hci_conn *conn;
2160
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002161 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002162
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002163 hci_dev_lock(hdev);
2164
2165 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002166 if (!conn)
2167 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002168
Johan Hedbergccd556f2010-11-10 17:11:51 +02002169 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002170 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002171
2172 if (conn->state != BT_CONFIG)
2173 goto unlock;
2174
2175 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2176 struct hci_cp_read_remote_ext_features cp;
2177 cp.handle = ev->handle;
2178 cp.page = 0x01;
2179 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002180 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002181 goto unlock;
2182 }
2183
Johan Hedberg671267b2012-05-12 16:11:50 -03002184 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002185 struct hci_cp_remote_name_req cp;
2186 memset(&cp, 0, sizeof(cp));
2187 bacpy(&cp.bdaddr, &conn->dst);
2188 cp.pscan_rep_mode = 0x02;
2189 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002190 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2191 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002192 conn->dst_type, 0, NULL, 0,
2193 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002194
Johan Hedberg127178d2010-11-18 22:22:29 +02002195 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002196 conn->state = BT_CONNECTED;
2197 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002198 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002199 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002200
Johan Hedbergccd556f2010-11-10 17:11:51 +02002201unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002202 hci_dev_unlock(hdev);
2203}
2204
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002205static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002206{
2207 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002208 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002209 __u16 opcode;
2210
2211 skb_pull(skb, sizeof(*ev));
2212
2213 opcode = __le16_to_cpu(ev->opcode);
2214
2215 switch (opcode) {
2216 case HCI_OP_INQUIRY_CANCEL:
2217 hci_cc_inquiry_cancel(hdev, skb);
2218 break;
2219
Andre Guedes4d934832012-03-21 00:03:35 -03002220 case HCI_OP_PERIODIC_INQ:
2221 hci_cc_periodic_inq(hdev, skb);
2222 break;
2223
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002224 case HCI_OP_EXIT_PERIODIC_INQ:
2225 hci_cc_exit_periodic_inq(hdev, skb);
2226 break;
2227
2228 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2229 hci_cc_remote_name_req_cancel(hdev, skb);
2230 break;
2231
2232 case HCI_OP_ROLE_DISCOVERY:
2233 hci_cc_role_discovery(hdev, skb);
2234 break;
2235
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002236 case HCI_OP_READ_LINK_POLICY:
2237 hci_cc_read_link_policy(hdev, skb);
2238 break;
2239
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002240 case HCI_OP_WRITE_LINK_POLICY:
2241 hci_cc_write_link_policy(hdev, skb);
2242 break;
2243
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002244 case HCI_OP_READ_DEF_LINK_POLICY:
2245 hci_cc_read_def_link_policy(hdev, skb);
2246 break;
2247
2248 case HCI_OP_WRITE_DEF_LINK_POLICY:
2249 hci_cc_write_def_link_policy(hdev, skb);
2250 break;
2251
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002252 case HCI_OP_RESET:
2253 hci_cc_reset(hdev, skb);
2254 break;
2255
2256 case HCI_OP_WRITE_LOCAL_NAME:
2257 hci_cc_write_local_name(hdev, skb);
2258 break;
2259
2260 case HCI_OP_READ_LOCAL_NAME:
2261 hci_cc_read_local_name(hdev, skb);
2262 break;
2263
2264 case HCI_OP_WRITE_AUTH_ENABLE:
2265 hci_cc_write_auth_enable(hdev, skb);
2266 break;
2267
2268 case HCI_OP_WRITE_ENCRYPT_MODE:
2269 hci_cc_write_encrypt_mode(hdev, skb);
2270 break;
2271
2272 case HCI_OP_WRITE_SCAN_ENABLE:
2273 hci_cc_write_scan_enable(hdev, skb);
2274 break;
2275
2276 case HCI_OP_READ_CLASS_OF_DEV:
2277 hci_cc_read_class_of_dev(hdev, skb);
2278 break;
2279
2280 case HCI_OP_WRITE_CLASS_OF_DEV:
2281 hci_cc_write_class_of_dev(hdev, skb);
2282 break;
2283
2284 case HCI_OP_READ_VOICE_SETTING:
2285 hci_cc_read_voice_setting(hdev, skb);
2286 break;
2287
2288 case HCI_OP_WRITE_VOICE_SETTING:
2289 hci_cc_write_voice_setting(hdev, skb);
2290 break;
2291
Marcel Holtmannb4cb9fb2013-10-14 13:56:16 -07002292 case HCI_OP_READ_NUM_SUPPORTED_IAC:
2293 hci_cc_read_num_supported_iac(hdev, skb);
2294 break;
2295
Marcel Holtmann333140b2008-07-14 20:13:48 +02002296 case HCI_OP_WRITE_SSP_MODE:
2297 hci_cc_write_ssp_mode(hdev, skb);
2298 break;
2299
Marcel Holtmanneac83dc2014-01-10 02:07:23 -08002300 case HCI_OP_WRITE_SC_SUPPORT:
2301 hci_cc_write_sc_support(hdev, skb);
2302 break;
2303
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002304 case HCI_OP_READ_LOCAL_VERSION:
2305 hci_cc_read_local_version(hdev, skb);
2306 break;
2307
2308 case HCI_OP_READ_LOCAL_COMMANDS:
2309 hci_cc_read_local_commands(hdev, skb);
2310 break;
2311
2312 case HCI_OP_READ_LOCAL_FEATURES:
2313 hci_cc_read_local_features(hdev, skb);
2314 break;
2315
Andre Guedes971e3a42011-06-30 19:20:52 -03002316 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2317 hci_cc_read_local_ext_features(hdev, skb);
2318 break;
2319
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002320 case HCI_OP_READ_BUFFER_SIZE:
2321 hci_cc_read_buffer_size(hdev, skb);
2322 break;
2323
2324 case HCI_OP_READ_BD_ADDR:
2325 hci_cc_read_bd_addr(hdev, skb);
2326 break;
2327
Johan Hedbergf332ec62013-03-15 17:07:11 -05002328 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2329 hci_cc_read_page_scan_activity(hdev, skb);
2330 break;
2331
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002332 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2333 hci_cc_write_page_scan_activity(hdev, skb);
2334 break;
2335
Johan Hedbergf332ec62013-03-15 17:07:11 -05002336 case HCI_OP_READ_PAGE_SCAN_TYPE:
2337 hci_cc_read_page_scan_type(hdev, skb);
2338 break;
2339
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002340 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2341 hci_cc_write_page_scan_type(hdev, skb);
2342 break;
2343
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002344 case HCI_OP_READ_DATA_BLOCK_SIZE:
2345 hci_cc_read_data_block_size(hdev, skb);
2346 break;
2347
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002348 case HCI_OP_READ_FLOW_CONTROL_MODE:
2349 hci_cc_read_flow_control_mode(hdev, skb);
2350 break;
2351
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002352 case HCI_OP_READ_LOCAL_AMP_INFO:
2353 hci_cc_read_local_amp_info(hdev, skb);
2354 break;
2355
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002356 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2357 hci_cc_read_local_amp_assoc(hdev, skb);
2358 break;
2359
Johan Hedbergd5859e22011-01-25 01:19:58 +02002360 case HCI_OP_READ_INQ_RSP_TX_POWER:
2361 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2362 break;
2363
Johan Hedberg980e1a52011-01-22 06:10:07 +02002364 case HCI_OP_PIN_CODE_REPLY:
2365 hci_cc_pin_code_reply(hdev, skb);
2366 break;
2367
2368 case HCI_OP_PIN_CODE_NEG_REPLY:
2369 hci_cc_pin_code_neg_reply(hdev, skb);
2370 break;
2371
Szymon Jancc35938b2011-03-22 13:12:21 +01002372 case HCI_OP_READ_LOCAL_OOB_DATA:
Marcel Holtmann4d2d2792014-01-10 02:07:26 -08002373 hci_cc_read_local_oob_data(hdev, skb);
2374 break;
2375
2376 case HCI_OP_READ_LOCAL_OOB_EXT_DATA:
2377 hci_cc_read_local_oob_ext_data(hdev, skb);
Szymon Jancc35938b2011-03-22 13:12:21 +01002378 break;
2379
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002380 case HCI_OP_LE_READ_BUFFER_SIZE:
2381 hci_cc_le_read_buffer_size(hdev, skb);
2382 break;
2383
Johan Hedberg60e77322013-01-22 14:01:59 +02002384 case HCI_OP_LE_READ_LOCAL_FEATURES:
2385 hci_cc_le_read_local_features(hdev, skb);
2386 break;
2387
Johan Hedberg8fa19092012-10-19 20:57:49 +03002388 case HCI_OP_LE_READ_ADV_TX_POWER:
2389 hci_cc_le_read_adv_tx_power(hdev, skb);
2390 break;
2391
Johan Hedberga5c29682011-02-19 12:05:57 -03002392 case HCI_OP_USER_CONFIRM_REPLY:
2393 hci_cc_user_confirm_reply(hdev, skb);
2394 break;
2395
2396 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2397 hci_cc_user_confirm_neg_reply(hdev, skb);
2398 break;
2399
Brian Gix1143d452011-11-23 08:28:34 -08002400 case HCI_OP_USER_PASSKEY_REPLY:
2401 hci_cc_user_passkey_reply(hdev, skb);
2402 break;
2403
2404 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2405 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002406 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002407
Marcel Holtmann7a4cd512014-02-19 19:52:13 -08002408 case HCI_OP_LE_SET_RANDOM_ADDR:
2409 hci_cc_le_set_random_addr(hdev, skb);
2410 break;
2411
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002412 case HCI_OP_LE_SET_ADV_ENABLE:
2413 hci_cc_le_set_adv_enable(hdev, skb);
2414 break;
2415
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002416 case HCI_OP_LE_SET_SCAN_ENABLE:
2417 hci_cc_le_set_scan_enable(hdev, skb);
2418 break;
2419
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002420 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2421 hci_cc_le_read_white_list_size(hdev, skb);
2422 break;
2423
Marcel Holtmann0f36b582014-02-27 20:37:31 -08002424 case HCI_OP_LE_CLEAR_WHITE_LIST:
2425 hci_cc_le_clear_white_list(hdev, skb);
2426 break;
2427
2428 case HCI_OP_LE_ADD_TO_WHITE_LIST:
2429 hci_cc_le_add_to_white_list(hdev, skb);
2430 break;
2431
2432 case HCI_OP_LE_DEL_FROM_WHITE_LIST:
2433 hci_cc_le_del_from_white_list(hdev, skb);
2434 break;
2435
Johan Hedberg9b008c02013-01-22 14:02:01 +02002436 case HCI_OP_LE_READ_SUPPORTED_STATES:
2437 hci_cc_le_read_supported_states(hdev, skb);
2438 break;
2439
Andre Guedesf9b49302011-06-30 19:20:53 -03002440 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2441 hci_cc_write_le_host_supported(hdev, skb);
2442 break;
2443
Johan Hedberg56ed2cb2014-02-27 14:05:40 +02002444 case HCI_OP_LE_SET_ADV_PARAM:
2445 hci_cc_set_adv_param(hdev, skb);
2446 break;
2447
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002448 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2449 hci_cc_write_remote_amp_assoc(hdev, skb);
2450 break;
2451
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002452 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002453 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002454 break;
2455 }
2456
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002457 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002458 del_timer(&hdev->cmd_timer);
2459
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002460 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002461
Szymon Jancdbccd792012-12-11 08:51:19 +01002462 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002463 atomic_set(&hdev->cmd_cnt, 1);
2464 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002465 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002466 }
2467}
2468
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002469static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002470{
2471 struct hci_ev_cmd_status *ev = (void *) skb->data;
2472 __u16 opcode;
2473
2474 skb_pull(skb, sizeof(*ev));
2475
2476 opcode = __le16_to_cpu(ev->opcode);
2477
2478 switch (opcode) {
2479 case HCI_OP_INQUIRY:
2480 hci_cs_inquiry(hdev, ev->status);
2481 break;
2482
2483 case HCI_OP_CREATE_CONN:
2484 hci_cs_create_conn(hdev, ev->status);
2485 break;
2486
2487 case HCI_OP_ADD_SCO:
2488 hci_cs_add_sco(hdev, ev->status);
2489 break;
2490
Marcel Holtmannf8558552008-07-14 20:13:49 +02002491 case HCI_OP_AUTH_REQUESTED:
2492 hci_cs_auth_requested(hdev, ev->status);
2493 break;
2494
2495 case HCI_OP_SET_CONN_ENCRYPT:
2496 hci_cs_set_conn_encrypt(hdev, ev->status);
2497 break;
2498
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002499 case HCI_OP_REMOTE_NAME_REQ:
2500 hci_cs_remote_name_req(hdev, ev->status);
2501 break;
2502
Marcel Holtmann769be972008-07-14 20:13:49 +02002503 case HCI_OP_READ_REMOTE_FEATURES:
2504 hci_cs_read_remote_features(hdev, ev->status);
2505 break;
2506
2507 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2508 hci_cs_read_remote_ext_features(hdev, ev->status);
2509 break;
2510
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002511 case HCI_OP_SETUP_SYNC_CONN:
2512 hci_cs_setup_sync_conn(hdev, ev->status);
2513 break;
2514
2515 case HCI_OP_SNIFF_MODE:
2516 hci_cs_sniff_mode(hdev, ev->status);
2517 break;
2518
2519 case HCI_OP_EXIT_SNIFF_MODE:
2520 hci_cs_exit_sniff_mode(hdev, ev->status);
2521 break;
2522
Johan Hedberg8962ee72011-01-20 12:40:27 +02002523 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002524 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002525 break;
2526
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002527 case HCI_OP_CREATE_PHY_LINK:
2528 hci_cs_create_phylink(hdev, ev->status);
2529 break;
2530
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002531 case HCI_OP_ACCEPT_PHY_LINK:
2532 hci_cs_accept_phylink(hdev, ev->status);
2533 break;
2534
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002535 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002536 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002537 break;
2538 }
2539
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002540 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002541 del_timer(&hdev->cmd_timer);
2542
Johan Hedberg02350a72013-04-03 21:50:29 +03002543 if (ev->status ||
2544 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2545 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002546
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002547 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002548 atomic_set(&hdev->cmd_cnt, 1);
2549 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002550 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002551 }
2552}
2553
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002554static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002555{
2556 struct hci_ev_role_change *ev = (void *) skb->data;
2557 struct hci_conn *conn;
2558
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002559 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002560
2561 hci_dev_lock(hdev);
2562
2563 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2564 if (conn) {
2565 if (!ev->status) {
2566 if (ev->role)
2567 conn->link_mode &= ~HCI_LM_MASTER;
2568 else
2569 conn->link_mode |= HCI_LM_MASTER;
2570 }
2571
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002572 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002573
2574 hci_role_switch_cfm(conn, ev->status, ev->role);
2575 }
2576
2577 hci_dev_unlock(hdev);
2578}
2579
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002580static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002581{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002582 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002583 int i;
2584
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002585 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2586 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2587 return;
2588 }
2589
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002590 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002591 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002592 BT_DBG("%s bad parameters", hdev->name);
2593 return;
2594 }
2595
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002596 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2597
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002598 for (i = 0; i < ev->num_hndl; i++) {
2599 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600 struct hci_conn *conn;
2601 __u16 handle, count;
2602
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002603 handle = __le16_to_cpu(info->handle);
2604 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002605
2606 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002607 if (!conn)
2608 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002610 conn->sent -= count;
2611
2612 switch (conn->type) {
2613 case ACL_LINK:
2614 hdev->acl_cnt += count;
2615 if (hdev->acl_cnt > hdev->acl_pkts)
2616 hdev->acl_cnt = hdev->acl_pkts;
2617 break;
2618
2619 case LE_LINK:
2620 if (hdev->le_pkts) {
2621 hdev->le_cnt += count;
2622 if (hdev->le_cnt > hdev->le_pkts)
2623 hdev->le_cnt = hdev->le_pkts;
2624 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002625 hdev->acl_cnt += count;
2626 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627 hdev->acl_cnt = hdev->acl_pkts;
2628 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002629 break;
2630
2631 case SCO_LINK:
2632 hdev->sco_cnt += count;
2633 if (hdev->sco_cnt > hdev->sco_pkts)
2634 hdev->sco_cnt = hdev->sco_pkts;
2635 break;
2636
2637 default:
2638 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2639 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640 }
2641 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002642
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002643 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002644}
2645
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002646static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2647 __u16 handle)
2648{
2649 struct hci_chan *chan;
2650
2651 switch (hdev->dev_type) {
2652 case HCI_BREDR:
2653 return hci_conn_hash_lookup_handle(hdev, handle);
2654 case HCI_AMP:
2655 chan = hci_chan_lookup_handle(hdev, handle);
2656 if (chan)
2657 return chan->conn;
2658 break;
2659 default:
2660 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2661 break;
2662 }
2663
2664 return NULL;
2665}
2666
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002667static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002668{
2669 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2670 int i;
2671
2672 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2673 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2674 return;
2675 }
2676
2677 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002678 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002679 BT_DBG("%s bad parameters", hdev->name);
2680 return;
2681 }
2682
2683 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002684 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002685
2686 for (i = 0; i < ev->num_hndl; i++) {
2687 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002688 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002689 __u16 handle, block_count;
2690
2691 handle = __le16_to_cpu(info->handle);
2692 block_count = __le16_to_cpu(info->blocks);
2693
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002694 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002695 if (!conn)
2696 continue;
2697
2698 conn->sent -= block_count;
2699
2700 switch (conn->type) {
2701 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002702 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002703 hdev->block_cnt += block_count;
2704 if (hdev->block_cnt > hdev->num_blocks)
2705 hdev->block_cnt = hdev->num_blocks;
2706 break;
2707
2708 default:
2709 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2710 break;
2711 }
2712 }
2713
2714 queue_work(hdev->workqueue, &hdev->tx_work);
2715}
2716
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002717static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002718{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002719 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002720 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002721
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002722 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723
2724 hci_dev_lock(hdev);
2725
Marcel Holtmann04837f62006-07-03 10:02:33 +02002726 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2727 if (conn) {
2728 conn->mode = ev->mode;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002729
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002730 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2731 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002732 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002733 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002734 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002735 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002736 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002737
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002738 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002739 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002740 }
2741
2742 hci_dev_unlock(hdev);
2743}
2744
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002745static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002746{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002747 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2748 struct hci_conn *conn;
2749
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002750 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002751
2752 hci_dev_lock(hdev);
2753
2754 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002755 if (!conn)
2756 goto unlock;
2757
2758 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002759 hci_conn_hold(conn);
2760 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002761 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002762 }
2763
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002764 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002765 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002766 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002767 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002768 u8 secure;
2769
2770 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2771 secure = 1;
2772 else
2773 secure = 0;
2774
Johan Hedberg744cf192011-11-08 20:40:14 +02002775 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002776 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002777
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002778unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002779 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002780}
2781
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002782static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002783{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002784 struct hci_ev_link_key_req *ev = (void *) skb->data;
2785 struct hci_cp_link_key_reply cp;
2786 struct hci_conn *conn;
2787 struct link_key *key;
2788
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002789 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002790
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002791 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002792 return;
2793
2794 hci_dev_lock(hdev);
2795
2796 key = hci_find_link_key(hdev, &ev->bdaddr);
2797 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002798 BT_DBG("%s link key not found for %pMR", hdev->name,
2799 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002800 goto not_found;
2801 }
2802
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002803 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2804 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002805
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002806 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002807 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002808 BT_DBG("%s ignoring debug key", hdev->name);
2809 goto not_found;
2810 }
2811
2812 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002813 if (conn) {
Marcel Holtmann66138ce2014-01-10 02:07:20 -08002814 if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
2815 key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002816 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002817 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2818 goto not_found;
2819 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002820
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002821 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002822 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002823 BT_DBG("%s ignoring key unauthenticated for high security",
2824 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002825 goto not_found;
2826 }
2827
2828 conn->key_type = key->type;
2829 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002830 }
2831
2832 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002833 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002834
2835 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2836
2837 hci_dev_unlock(hdev);
2838
2839 return;
2840
2841not_found:
2842 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2843 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002844}
2845
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002846static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002847{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002848 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2849 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002850 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002851
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002852 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002853
2854 hci_dev_lock(hdev);
2855
2856 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2857 if (conn) {
2858 hci_conn_hold(conn);
2859 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002860 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002861
2862 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2863 conn->key_type = ev->key_type;
2864
David Herrmann76a68ba2013-04-06 20:28:37 +02002865 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002866 }
2867
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002868 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002869 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002870 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002871
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002872 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002873}
2874
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002875static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002876{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002877 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002878 struct hci_conn *conn;
2879
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002880 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002881
2882 hci_dev_lock(hdev);
2883
2884 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002885 if (conn && !ev->status) {
2886 struct inquiry_entry *ie;
2887
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002888 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2889 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002890 ie->data.clock_offset = ev->clock_offset;
2891 ie->timestamp = jiffies;
2892 }
2893 }
2894
2895 hci_dev_unlock(hdev);
2896}
2897
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002898static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002899{
2900 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2901 struct hci_conn *conn;
2902
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002903 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002904
2905 hci_dev_lock(hdev);
2906
2907 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2908 if (conn && !ev->status)
2909 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2910
2911 hci_dev_unlock(hdev);
2912}
2913
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002914static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002915{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002916 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002917 struct inquiry_entry *ie;
2918
2919 BT_DBG("%s", hdev->name);
2920
2921 hci_dev_lock(hdev);
2922
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002923 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2924 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002925 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2926 ie->timestamp = jiffies;
2927 }
2928
2929 hci_dev_unlock(hdev);
2930}
2931
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002932static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2933 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002934{
2935 struct inquiry_data data;
2936 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002937 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002938
2939 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2940
2941 if (!num_rsp)
2942 return;
2943
Andre Guedes1519cc12012-03-21 00:03:38 -03002944 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2945 return;
2946
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002947 hci_dev_lock(hdev);
2948
2949 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002950 struct inquiry_info_with_rssi_and_pscan_mode *info;
2951 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002952
Johan Hedberge17acd42011-03-30 23:57:16 +03002953 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002954 bacpy(&data.bdaddr, &info->bdaddr);
2955 data.pscan_rep_mode = info->pscan_rep_mode;
2956 data.pscan_period_mode = info->pscan_period_mode;
2957 data.pscan_mode = info->pscan_mode;
2958 memcpy(data.dev_class, info->dev_class, 3);
2959 data.clock_offset = info->clock_offset;
2960 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002961 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002962
2963 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002964 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002965 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002966 info->dev_class, info->rssi,
2967 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002968 }
2969 } else {
2970 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2971
Johan Hedberge17acd42011-03-30 23:57:16 +03002972 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002973 bacpy(&data.bdaddr, &info->bdaddr);
2974 data.pscan_rep_mode = info->pscan_rep_mode;
2975 data.pscan_period_mode = info->pscan_period_mode;
2976 data.pscan_mode = 0x00;
2977 memcpy(data.dev_class, info->dev_class, 3);
2978 data.clock_offset = info->clock_offset;
2979 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002980 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002981 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002982 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002983 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002984 info->dev_class, info->rssi,
2985 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002986 }
2987 }
2988
2989 hci_dev_unlock(hdev);
2990}
2991
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002992static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2993 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002994{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002995 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2996 struct hci_conn *conn;
2997
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002998 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002999
Marcel Holtmann41a96212008-07-14 20:13:48 +02003000 hci_dev_lock(hdev);
3001
3002 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02003003 if (!conn)
3004 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003005
Johan Hedbergcad718e2013-04-17 15:00:51 +03003006 if (ev->page < HCI_MAX_PAGES)
3007 memcpy(conn->features[ev->page], ev->features, 8);
3008
Johan Hedbergccd556f2010-11-10 17:11:51 +02003009 if (!ev->status && ev->page == 0x01) {
3010 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003011
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003012 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3013 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003014 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02003015
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05303016 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02003017 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05303018 } else {
3019 /* It is mandatory by the Bluetooth specification that
3020 * Extended Inquiry Results are only used when Secure
3021 * Simple Pairing is enabled, but some devices violate
3022 * this.
3023 *
3024 * To make these devices work, the internal SSP
3025 * enabled flag needs to be cleared if the remote host
3026 * features do not indicate SSP support */
3027 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
3028 }
Marcel Holtmanneb9a8f32014-01-15 22:37:38 -08003029
3030 if (ev->features[0] & LMP_HOST_SC)
3031 set_bit(HCI_CONN_SC_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003032 }
3033
Johan Hedbergccd556f2010-11-10 17:11:51 +02003034 if (conn->state != BT_CONFIG)
3035 goto unlock;
3036
Johan Hedberg671267b2012-05-12 16:11:50 -03003037 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02003038 struct hci_cp_remote_name_req cp;
3039 memset(&cp, 0, sizeof(cp));
3040 bacpy(&cp.bdaddr, &conn->dst);
3041 cp.pscan_rep_mode = 0x02;
3042 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02003043 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3044 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003045 conn->dst_type, 0, NULL, 0,
3046 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02003047
Johan Hedberg127178d2010-11-18 22:22:29 +02003048 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02003049 conn->state = BT_CONNECTED;
3050 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003051 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02003052 }
3053
3054unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02003055 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003056}
3057
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003058static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
3059 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003060{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003061 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
3062 struct hci_conn *conn;
3063
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003064 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003065
3066 hci_dev_lock(hdev);
3067
3068 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02003069 if (!conn) {
3070 if (ev->link_type == ESCO_LINK)
3071 goto unlock;
3072
3073 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
3074 if (!conn)
3075 goto unlock;
3076
3077 conn->type = SCO_LINK;
3078 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003079
Marcel Holtmann732547f2009-04-19 19:14:14 +02003080 switch (ev->status) {
3081 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003082 conn->handle = __le16_to_cpu(ev->handle);
3083 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02003084
3085 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02003086 break;
3087
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02003088 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05003089 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003090 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08003091 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003092 case 0x1f: /* Unspecified error */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003093 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02003094 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
3095 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02003096 if (hci_setup_sync(conn, conn->link->handle))
3097 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003098 }
3099 /* fall through */
3100
3101 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003102 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003103 break;
3104 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003105
3106 hci_proto_connect_cfm(conn, ev->status);
3107 if (ev->status)
3108 hci_conn_del(conn);
3109
3110unlock:
3111 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003112}
3113
Marcel Holtmannefdcf8e2013-10-15 10:31:12 -07003114static inline size_t eir_get_length(u8 *eir, size_t eir_len)
3115{
3116 size_t parsed = 0;
3117
3118 while (parsed < eir_len) {
3119 u8 field_len = eir[0];
3120
3121 if (field_len == 0)
3122 return parsed;
3123
3124 parsed += field_len + 1;
3125 eir += field_len + 1;
3126 }
3127
3128 return eir_len;
3129}
3130
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003131static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3132 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003133{
3134 struct inquiry_data data;
3135 struct extended_inquiry_info *info = (void *) (skb->data + 1);
3136 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303137 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003138
3139 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3140
3141 if (!num_rsp)
3142 return;
3143
Andre Guedes1519cc12012-03-21 00:03:38 -03003144 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3145 return;
3146
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003147 hci_dev_lock(hdev);
3148
Johan Hedberge17acd42011-03-30 23:57:16 +03003149 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003150 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003151
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003152 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003153 data.pscan_rep_mode = info->pscan_rep_mode;
3154 data.pscan_period_mode = info->pscan_period_mode;
3155 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003156 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003157 data.clock_offset = info->clock_offset;
3158 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003159 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003160
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003161 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003162 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003163 sizeof(info->data),
3164 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003165 else
3166 name_known = true;
3167
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003168 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003169 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303170 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003171 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003172 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303173 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003174 }
3175
3176 hci_dev_unlock(hdev);
3177}
3178
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003179static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3180 struct sk_buff *skb)
3181{
3182 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3183 struct hci_conn *conn;
3184
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003185 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003186 __le16_to_cpu(ev->handle));
3187
3188 hci_dev_lock(hdev);
3189
3190 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3191 if (!conn)
3192 goto unlock;
3193
3194 if (!ev->status)
3195 conn->sec_level = conn->pending_sec_level;
3196
3197 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3198
3199 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003200 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003201 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003202 goto unlock;
3203 }
3204
3205 if (conn->state == BT_CONFIG) {
3206 if (!ev->status)
3207 conn->state = BT_CONNECTED;
3208
3209 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003210 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003211 } else {
3212 hci_auth_cfm(conn, ev->status);
3213
3214 hci_conn_hold(conn);
3215 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003216 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003217 }
3218
3219unlock:
3220 hci_dev_unlock(hdev);
3221}
3222
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003223static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003224{
3225 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003226 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3227 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003228 /* If both remote and local IO capabilities allow MITM
3229 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003230 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3231 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3232 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003233 else
Mikel Astizacabae92013-06-28 10:56:28 +02003234 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003235 }
3236
3237 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003238 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3239 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003240 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003241
3242 return conn->auth_type;
3243}
3244
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003245static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003246{
3247 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3248 struct hci_conn *conn;
3249
3250 BT_DBG("%s", hdev->name);
3251
3252 hci_dev_lock(hdev);
3253
3254 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003255 if (!conn)
3256 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003257
Johan Hedberg03b555e2011-01-04 15:40:05 +02003258 hci_conn_hold(conn);
3259
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003260 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003261 goto unlock;
3262
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003263 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003264 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003265 struct hci_cp_io_capability_reply cp;
3266
3267 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303268 /* Change the IO capability from KeyboardDisplay
3269 * to DisplayYesNo as it is not supported by BT spec. */
3270 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003271 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003272 conn->auth_type = hci_get_auth_req(conn);
3273 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003274
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003275 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3276 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003277 cp.oob_data = 0x01;
3278 else
3279 cp.oob_data = 0x00;
3280
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003281 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003282 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003283 } else {
3284 struct hci_cp_io_capability_neg_reply cp;
3285
3286 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003287 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003288
3289 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003290 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003291 }
3292
3293unlock:
3294 hci_dev_unlock(hdev);
3295}
3296
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003297static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003298{
3299 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3300 struct hci_conn *conn;
3301
3302 BT_DBG("%s", hdev->name);
3303
3304 hci_dev_lock(hdev);
3305
3306 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3307 if (!conn)
3308 goto unlock;
3309
Johan Hedberg03b555e2011-01-04 15:40:05 +02003310 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003311 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003312 if (ev->oob_data)
3313 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003314
3315unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003316 hci_dev_unlock(hdev);
3317}
3318
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003319static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3320 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003321{
3322 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003323 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003324 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003325
3326 BT_DBG("%s", hdev->name);
3327
3328 hci_dev_lock(hdev);
3329
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003330 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003331 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003332
Johan Hedberg7a828902011-04-28 11:28:53 -07003333 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3334 if (!conn)
3335 goto unlock;
3336
3337 loc_mitm = (conn->auth_type & 0x01);
3338 rem_mitm = (conn->remote_auth & 0x01);
3339
3340 /* If we require MITM but the remote device can't provide that
3341 * (it has NoInputNoOutput) then reject the confirmation
3342 * request. The only exception is when we're dedicated bonding
3343 * initiators (connect_cfm_cb set) since then we always have the MITM
3344 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003345 if (!conn->connect_cfm_cb && loc_mitm &&
3346 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003347 BT_DBG("Rejecting request: remote device can't provide MITM");
3348 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003349 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003350 goto unlock;
3351 }
3352
3353 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003354 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3355 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003356
3357 /* If we're not the initiators request authorization to
3358 * proceed from user space (mgmt_user_confirm with
3359 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003360 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003361 BT_DBG("Confirming auto-accept as acceptor");
3362 confirm_hint = 1;
3363 goto confirm;
3364 }
3365
Johan Hedberg9f616562011-04-28 11:28:54 -07003366 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003367 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003368
3369 if (hdev->auto_accept_delay > 0) {
3370 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
Johan Hedberg7bc18d92013-10-16 18:11:39 +03003371 queue_delayed_work(conn->hdev->workqueue,
3372 &conn->auto_accept_work, delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003373 goto unlock;
3374 }
3375
Johan Hedberg7a828902011-04-28 11:28:53 -07003376 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003377 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003378 goto unlock;
3379 }
3380
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003381confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003382 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003383 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003384
3385unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003386 hci_dev_unlock(hdev);
3387}
3388
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003389static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3390 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003391{
3392 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3393
3394 BT_DBG("%s", hdev->name);
3395
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003396 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003397 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003398}
3399
Johan Hedberg92a25252012-09-06 18:39:26 +03003400static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3401 struct sk_buff *skb)
3402{
3403 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3404 struct hci_conn *conn;
3405
3406 BT_DBG("%s", hdev->name);
3407
3408 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3409 if (!conn)
3410 return;
3411
3412 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3413 conn->passkey_entered = 0;
3414
3415 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3416 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3417 conn->dst_type, conn->passkey_notify,
3418 conn->passkey_entered);
3419}
3420
3421static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3422{
3423 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3424 struct hci_conn *conn;
3425
3426 BT_DBG("%s", hdev->name);
3427
3428 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3429 if (!conn)
3430 return;
3431
3432 switch (ev->type) {
3433 case HCI_KEYPRESS_STARTED:
3434 conn->passkey_entered = 0;
3435 return;
3436
3437 case HCI_KEYPRESS_ENTERED:
3438 conn->passkey_entered++;
3439 break;
3440
3441 case HCI_KEYPRESS_ERASED:
3442 conn->passkey_entered--;
3443 break;
3444
3445 case HCI_KEYPRESS_CLEARED:
3446 conn->passkey_entered = 0;
3447 break;
3448
3449 case HCI_KEYPRESS_COMPLETED:
3450 return;
3451 }
3452
3453 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3454 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3455 conn->dst_type, conn->passkey_notify,
3456 conn->passkey_entered);
3457}
3458
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003459static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3460 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003461{
3462 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3463 struct hci_conn *conn;
3464
3465 BT_DBG("%s", hdev->name);
3466
3467 hci_dev_lock(hdev);
3468
3469 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003470 if (!conn)
3471 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003472
Johan Hedberg2a611692011-02-19 12:06:00 -03003473 /* To avoid duplicate auth_failed events to user space we check
3474 * the HCI_CONN_AUTH_PEND flag which will be set if we
3475 * initiated the authentication. A traditional auth_complete
3476 * event gets always produced as initiator and is also mapped to
3477 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003478 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003479 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003480 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003481
David Herrmann76a68ba2013-04-06 20:28:37 +02003482 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003483
3484unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003485 hci_dev_unlock(hdev);
3486}
3487
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003488static void hci_remote_host_features_evt(struct hci_dev *hdev,
3489 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003490{
3491 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3492 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003493 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003494
3495 BT_DBG("%s", hdev->name);
3496
3497 hci_dev_lock(hdev);
3498
Johan Hedbergcad718e2013-04-17 15:00:51 +03003499 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3500 if (conn)
3501 memcpy(conn->features[1], ev->features, 8);
3502
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003503 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3504 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003505 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003506
3507 hci_dev_unlock(hdev);
3508}
3509
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003510static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3511 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003512{
3513 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3514 struct oob_data *data;
3515
3516 BT_DBG("%s", hdev->name);
3517
3518 hci_dev_lock(hdev);
3519
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003520 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003521 goto unlock;
3522
Szymon Janc2763eda2011-03-22 13:12:22 +01003523 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3524 if (data) {
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003525 if (test_bit(HCI_SC_ENABLED, &hdev->dev_flags)) {
3526 struct hci_cp_remote_oob_ext_data_reply cp;
Szymon Janc2763eda2011-03-22 13:12:22 +01003527
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003528 bacpy(&cp.bdaddr, &ev->bdaddr);
3529 memcpy(cp.hash192, data->hash192, sizeof(cp.hash192));
3530 memcpy(cp.randomizer192, data->randomizer192,
3531 sizeof(cp.randomizer192));
3532 memcpy(cp.hash256, data->hash256, sizeof(cp.hash256));
3533 memcpy(cp.randomizer256, data->randomizer256,
3534 sizeof(cp.randomizer256));
Szymon Janc2763eda2011-03-22 13:12:22 +01003535
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003536 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_EXT_DATA_REPLY,
3537 sizeof(cp), &cp);
3538 } else {
3539 struct hci_cp_remote_oob_data_reply cp;
3540
3541 bacpy(&cp.bdaddr, &ev->bdaddr);
3542 memcpy(cp.hash, data->hash192, sizeof(cp.hash));
3543 memcpy(cp.randomizer, data->randomizer192,
3544 sizeof(cp.randomizer));
3545
3546 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY,
3547 sizeof(cp), &cp);
3548 }
Szymon Janc2763eda2011-03-22 13:12:22 +01003549 } else {
3550 struct hci_cp_remote_oob_data_neg_reply cp;
3551
3552 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmann519ca9d2014-01-10 02:07:28 -08003553 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY,
3554 sizeof(cp), &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003555 }
3556
Szymon Jance1ba1f12011-04-06 13:01:59 +02003557unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003558 hci_dev_unlock(hdev);
3559}
3560
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003561static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3562 struct sk_buff *skb)
3563{
3564 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3565 struct hci_conn *hcon, *bredr_hcon;
3566
3567 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3568 ev->status);
3569
3570 hci_dev_lock(hdev);
3571
3572 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3573 if (!hcon) {
3574 hci_dev_unlock(hdev);
3575 return;
3576 }
3577
3578 if (ev->status) {
3579 hci_conn_del(hcon);
3580 hci_dev_unlock(hdev);
3581 return;
3582 }
3583
3584 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3585
3586 hcon->state = BT_CONNECTED;
3587 bacpy(&hcon->dst, &bredr_hcon->dst);
3588
3589 hci_conn_hold(hcon);
3590 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003591 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003592
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003593 hci_conn_add_sysfs(hcon);
3594
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003595 amp_physical_cfm(bredr_hcon, hcon);
3596
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003597 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003598}
3599
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003600static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3601{
3602 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3603 struct hci_conn *hcon;
3604 struct hci_chan *hchan;
3605 struct amp_mgr *mgr;
3606
3607 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3608 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3609 ev->status);
3610
3611 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3612 if (!hcon)
3613 return;
3614
3615 /* Create AMP hchan */
3616 hchan = hci_chan_create(hcon);
3617 if (!hchan)
3618 return;
3619
3620 hchan->handle = le16_to_cpu(ev->handle);
3621
3622 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3623
3624 mgr = hcon->amp_mgr;
3625 if (mgr && mgr->bredr_chan) {
3626 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3627
3628 l2cap_chan_lock(bredr_chan);
3629
3630 bredr_chan->conn->mtu = hdev->block_mtu;
3631 l2cap_logical_cfm(bredr_chan, hchan, 0);
3632 hci_conn_hold(hcon);
3633
3634 l2cap_chan_unlock(bredr_chan);
3635 }
3636}
3637
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003638static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3639 struct sk_buff *skb)
3640{
3641 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3642 struct hci_chan *hchan;
3643
3644 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3645 le16_to_cpu(ev->handle), ev->status);
3646
3647 if (ev->status)
3648 return;
3649
3650 hci_dev_lock(hdev);
3651
3652 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3653 if (!hchan)
3654 goto unlock;
3655
3656 amp_destroy_logical_link(hchan, ev->reason);
3657
3658unlock:
3659 hci_dev_unlock(hdev);
3660}
3661
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003662static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3663 struct sk_buff *skb)
3664{
3665 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3666 struct hci_conn *hcon;
3667
3668 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3669
3670 if (ev->status)
3671 return;
3672
3673 hci_dev_lock(hdev);
3674
3675 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3676 if (hcon) {
3677 hcon->state = BT_CLOSED;
3678 hci_conn_del(hcon);
3679 }
3680
3681 hci_dev_unlock(hdev);
3682}
3683
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003684static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003685{
3686 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3687 struct hci_conn *conn;
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003688 struct smp_irk *irk;
Ville Tervofcd89c02011-02-10 22:38:47 -03003689
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003690 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003691
3692 hci_dev_lock(hdev);
3693
Andre Guedesb47a09b2012-07-27 15:10:15 -03003694 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003695 if (!conn) {
3696 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3697 if (!conn) {
3698 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003699 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003700 }
Andre Guedes29b79882011-05-31 14:20:54 -03003701
3702 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003703
Marcel Holtmann880be4e2013-10-13 07:25:18 -07003704 /* The advertising parameters for own address type
3705 * define which source address and source address
3706 * type this connections has.
3707 */
3708 if (bacmp(&conn->src, BDADDR_ANY)) {
3709 conn->src_type = ADDR_LE_DEV_PUBLIC;
3710 } else {
3711 bacpy(&conn->src, &hdev->static_addr);
3712 conn->src_type = ADDR_LE_DEV_RANDOM;
3713 }
3714
Andre Guedesb9b343d2012-07-27 15:10:11 -03003715 if (ev->role == LE_CONN_ROLE_MASTER) {
3716 conn->out = true;
3717 conn->link_mode |= HCI_LM_MASTER;
3718 }
Ville Tervob62f3282011-02-10 22:38:50 -03003719 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003720
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003721 /* Ensure that the hci_conn contains the identity address type
3722 * regardless of which address the connection was made with.
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003723 */
Johan Hedberga1f4c312014-02-27 14:05:41 +02003724 hci_copy_identity_address(hdev, &conn->src, &conn->src_type);
Johan Hedberg7be2edb2014-02-23 19:42:17 +02003725
Marcel Holtmannedb4b462014-02-18 15:13:43 -08003726 /* Lookup the identity address from the stored connection
3727 * address and address type.
3728 *
3729 * When establishing connections to an identity address, the
3730 * connection procedure will store the resolvable random
3731 * address first. Now if it can be converted back into the
3732 * identity address, start using the identity address from
3733 * now on.
3734 */
3735 irk = hci_get_irk(hdev, &conn->dst, conn->dst_type);
Johan Hedberg68d6f6d2014-02-18 21:41:32 +02003736 if (irk) {
3737 bacpy(&conn->dst, &irk->bdaddr);
3738 conn->dst_type = irk->addr_type;
3739 }
3740
Andre Guedescd17dec2012-07-27 15:10:16 -03003741 if (ev->status) {
Andre Guedes06c053f2014-02-26 20:21:41 -03003742 hci_le_conn_failed(conn, ev->status);
Andre Guedescd17dec2012-07-27 15:10:16 -03003743 goto unlock;
3744 }
3745
Johan Hedbergb644ba32012-01-17 21:48:47 +02003746 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Marcel Holtmann01fdb0f2014-02-18 14:22:19 -08003747 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003748 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003749
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003750 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003751 conn->handle = __le16_to_cpu(ev->handle);
3752 conn->state = BT_CONNECTED;
3753
Jukka Rissanen18722c22013-12-11 17:05:37 +02003754 if (test_bit(HCI_6LOWPAN_ENABLED, &hdev->dev_flags))
3755 set_bit(HCI_CONN_6LOWPAN, &conn->flags);
3756
Ville Tervofcd89c02011-02-10 22:38:47 -03003757 hci_conn_add_sysfs(conn);
3758
3759 hci_proto_connect_cfm(conn, ev->status);
3760
Andre Guedesa4790db2014-02-26 20:21:47 -03003761 hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type);
3762
Ville Tervofcd89c02011-02-10 22:38:47 -03003763unlock:
3764 hci_dev_unlock(hdev);
3765}
3766
Andre Guedesa4790db2014-02-26 20:21:47 -03003767/* This function requires the caller holds hdev->lock */
3768static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
3769 u8 addr_type)
3770{
3771 struct hci_conn *conn;
Andre Guedes5b906a82014-02-26 20:21:53 -03003772 struct smp_irk *irk;
3773
3774 /* If this is a resolvable address, we should resolve it and then
3775 * update address and address type variables.
3776 */
3777 irk = hci_get_irk(hdev, addr, addr_type);
3778 if (irk) {
3779 addr = &irk->bdaddr;
3780 addr_type = irk->addr_type;
3781 }
Andre Guedesa4790db2014-02-26 20:21:47 -03003782
3783 if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
3784 return;
3785
3786 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
3787 HCI_AT_NO_BONDING);
3788 if (!IS_ERR(conn))
3789 return;
3790
3791 switch (PTR_ERR(conn)) {
3792 case -EBUSY:
3793 /* If hci_connect() returns -EBUSY it means there is already
3794 * an LE connection attempt going on. Since controllers don't
3795 * support more than one connection attempt at the time, we
3796 * don't consider this an error case.
3797 */
3798 break;
3799 default:
3800 BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
3801 }
3802}
3803
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003804static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003805{
Andre Guedese95beb42011-09-26 20:48:35 -03003806 u8 num_reports = skb->data[0];
3807 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003808 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003809
Andre Guedesa4790db2014-02-26 20:21:47 -03003810 hci_dev_lock(hdev);
3811
Andre Guedese95beb42011-09-26 20:48:35 -03003812 while (num_reports--) {
3813 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003814
Andre Guedesa4790db2014-02-26 20:21:47 -03003815 if (ev->evt_type == LE_ADV_IND ||
3816 ev->evt_type == LE_ADV_DIRECT_IND)
3817 check_pending_le_conn(hdev, &ev->bdaddr,
3818 ev->bdaddr_type);
3819
Andre Guedes3c9e9192012-01-10 18:20:50 -03003820 rssi = ev->data[ev->length];
3821 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003822 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003823
Andre Guedese95beb42011-09-26 20:48:35 -03003824 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003825 }
Andre Guedesa4790db2014-02-26 20:21:47 -03003826
3827 hci_dev_unlock(hdev);
Andre Guedes9aa04c92011-05-26 16:23:51 -03003828}
3829
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003830static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003831{
3832 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3833 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003834 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003835 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003836 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003837
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003838 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003839
3840 hci_dev_lock(hdev);
3841
3842 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003843 if (conn == NULL)
3844 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003845
Marcel Holtmannfe39c7b2014-02-27 16:00:28 -08003846 ltk = hci_find_ltk(hdev, ev->ediv, ev->rand, conn->out);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003847 if (ltk == NULL)
3848 goto not_found;
3849
3850 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003851 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003852
3853 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03003854 conn->pending_sec_level = BT_SECURITY_HIGH;
3855 else
3856 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003857
Andre Guedes89cbb4d2013-07-31 16:25:29 -03003858 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003859
3860 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3861
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003862 if (ltk->type & HCI_SMP_STK) {
3863 list_del(&ltk->list);
3864 kfree(ltk);
3865 }
3866
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003867 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003868
3869 return;
3870
3871not_found:
3872 neg.handle = ev->handle;
3873 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3874 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003875}
3876
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003877static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003878{
3879 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3880
3881 skb_pull(skb, sizeof(*le_ev));
3882
3883 switch (le_ev->subevent) {
3884 case HCI_EV_LE_CONN_COMPLETE:
3885 hci_le_conn_complete_evt(hdev, skb);
3886 break;
3887
Andre Guedes9aa04c92011-05-26 16:23:51 -03003888 case HCI_EV_LE_ADVERTISING_REPORT:
3889 hci_le_adv_report_evt(hdev, skb);
3890 break;
3891
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003892 case HCI_EV_LE_LTK_REQ:
3893 hci_le_ltk_request_evt(hdev, skb);
3894 break;
3895
Ville Tervofcd89c02011-02-10 22:38:47 -03003896 default:
3897 break;
3898 }
3899}
3900
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003901static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3902{
3903 struct hci_ev_channel_selected *ev = (void *) skb->data;
3904 struct hci_conn *hcon;
3905
3906 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3907
3908 skb_pull(skb, sizeof(*ev));
3909
3910 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3911 if (!hcon)
3912 return;
3913
3914 amp_read_loc_assoc_final_data(hdev, hcon);
3915}
3916
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3918{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003919 struct hci_event_hdr *hdr = (void *) skb->data;
3920 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003921
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003922 hci_dev_lock(hdev);
3923
3924 /* Received events are (currently) only needed when a request is
3925 * ongoing so avoid unnecessary memory allocation.
3926 */
3927 if (hdev->req_status == HCI_REQ_PEND) {
3928 kfree_skb(hdev->recv_evt);
3929 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3930 }
3931
3932 hci_dev_unlock(hdev);
3933
Linus Torvalds1da177e2005-04-16 15:20:36 -07003934 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3935
Johan Hedberg02350a72013-04-03 21:50:29 +03003936 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
Johannes Bergc1f23a22013-10-07 18:19:16 +02003937 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
3938 u16 opcode = __le16_to_cpu(cmd_hdr->opcode);
Johan Hedberg02350a72013-04-03 21:50:29 +03003939
3940 hci_req_cmd_complete(hdev, opcode, 0);
3941 }
3942
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003943 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003944 case HCI_EV_INQUIRY_COMPLETE:
3945 hci_inquiry_complete_evt(hdev, skb);
3946 break;
3947
3948 case HCI_EV_INQUIRY_RESULT:
3949 hci_inquiry_result_evt(hdev, skb);
3950 break;
3951
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003952 case HCI_EV_CONN_COMPLETE:
3953 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003954 break;
3955
Linus Torvalds1da177e2005-04-16 15:20:36 -07003956 case HCI_EV_CONN_REQUEST:
3957 hci_conn_request_evt(hdev, skb);
3958 break;
3959
Linus Torvalds1da177e2005-04-16 15:20:36 -07003960 case HCI_EV_DISCONN_COMPLETE:
3961 hci_disconn_complete_evt(hdev, skb);
3962 break;
3963
Linus Torvalds1da177e2005-04-16 15:20:36 -07003964 case HCI_EV_AUTH_COMPLETE:
3965 hci_auth_complete_evt(hdev, skb);
3966 break;
3967
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003968 case HCI_EV_REMOTE_NAME:
3969 hci_remote_name_evt(hdev, skb);
3970 break;
3971
Linus Torvalds1da177e2005-04-16 15:20:36 -07003972 case HCI_EV_ENCRYPT_CHANGE:
3973 hci_encrypt_change_evt(hdev, skb);
3974 break;
3975
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003976 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3977 hci_change_link_key_complete_evt(hdev, skb);
3978 break;
3979
3980 case HCI_EV_REMOTE_FEATURES:
3981 hci_remote_features_evt(hdev, skb);
3982 break;
3983
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003984 case HCI_EV_CMD_COMPLETE:
3985 hci_cmd_complete_evt(hdev, skb);
3986 break;
3987
3988 case HCI_EV_CMD_STATUS:
3989 hci_cmd_status_evt(hdev, skb);
3990 break;
3991
3992 case HCI_EV_ROLE_CHANGE:
3993 hci_role_change_evt(hdev, skb);
3994 break;
3995
3996 case HCI_EV_NUM_COMP_PKTS:
3997 hci_num_comp_pkts_evt(hdev, skb);
3998 break;
3999
4000 case HCI_EV_MODE_CHANGE:
4001 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004002 break;
4003
4004 case HCI_EV_PIN_CODE_REQ:
4005 hci_pin_code_request_evt(hdev, skb);
4006 break;
4007
4008 case HCI_EV_LINK_KEY_REQ:
4009 hci_link_key_request_evt(hdev, skb);
4010 break;
4011
4012 case HCI_EV_LINK_KEY_NOTIFY:
4013 hci_link_key_notify_evt(hdev, skb);
4014 break;
4015
4016 case HCI_EV_CLOCK_OFFSET:
4017 hci_clock_offset_evt(hdev, skb);
4018 break;
4019
Marcel Holtmanna8746412008-07-14 20:13:46 +02004020 case HCI_EV_PKT_TYPE_CHANGE:
4021 hci_pkt_type_change_evt(hdev, skb);
4022 break;
4023
Marcel Holtmann85a1e932005-08-09 20:28:02 -07004024 case HCI_EV_PSCAN_REP_MODE:
4025 hci_pscan_rep_mode_evt(hdev, skb);
4026 break;
4027
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004028 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
4029 hci_inquiry_result_with_rssi_evt(hdev, skb);
4030 break;
4031
4032 case HCI_EV_REMOTE_EXT_FEATURES:
4033 hci_remote_ext_features_evt(hdev, skb);
4034 break;
4035
4036 case HCI_EV_SYNC_CONN_COMPLETE:
4037 hci_sync_conn_complete_evt(hdev, skb);
4038 break;
4039
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004040 case HCI_EV_EXTENDED_INQUIRY_RESULT:
4041 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004042 break;
4043
Johan Hedberg1c2e0042012-06-08 23:31:13 +08004044 case HCI_EV_KEY_REFRESH_COMPLETE:
4045 hci_key_refresh_complete_evt(hdev, skb);
4046 break;
4047
Marcel Holtmann04936842008-07-14 20:13:48 +02004048 case HCI_EV_IO_CAPA_REQUEST:
4049 hci_io_capa_request_evt(hdev, skb);
4050 break;
4051
Johan Hedberg03b555e2011-01-04 15:40:05 +02004052 case HCI_EV_IO_CAPA_REPLY:
4053 hci_io_capa_reply_evt(hdev, skb);
4054 break;
4055
Johan Hedberga5c29682011-02-19 12:05:57 -03004056 case HCI_EV_USER_CONFIRM_REQUEST:
4057 hci_user_confirm_request_evt(hdev, skb);
4058 break;
4059
Brian Gix1143d452011-11-23 08:28:34 -08004060 case HCI_EV_USER_PASSKEY_REQUEST:
4061 hci_user_passkey_request_evt(hdev, skb);
4062 break;
4063
Johan Hedberg92a25252012-09-06 18:39:26 +03004064 case HCI_EV_USER_PASSKEY_NOTIFY:
4065 hci_user_passkey_notify_evt(hdev, skb);
4066 break;
4067
4068 case HCI_EV_KEYPRESS_NOTIFY:
4069 hci_keypress_notify_evt(hdev, skb);
4070 break;
4071
Marcel Holtmann04936842008-07-14 20:13:48 +02004072 case HCI_EV_SIMPLE_PAIR_COMPLETE:
4073 hci_simple_pair_complete_evt(hdev, skb);
4074 break;
4075
Marcel Holtmann41a96212008-07-14 20:13:48 +02004076 case HCI_EV_REMOTE_HOST_FEATURES:
4077 hci_remote_host_features_evt(hdev, skb);
4078 break;
4079
Ville Tervofcd89c02011-02-10 22:38:47 -03004080 case HCI_EV_LE_META:
4081 hci_le_meta_evt(hdev, skb);
4082 break;
4083
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03004084 case HCI_EV_CHANNEL_SELECTED:
4085 hci_chan_selected_evt(hdev, skb);
4086 break;
4087
Szymon Janc2763eda2011-03-22 13:12:22 +01004088 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
4089 hci_remote_oob_data_request_evt(hdev, skb);
4090 break;
4091
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03004092 case HCI_EV_PHY_LINK_COMPLETE:
4093 hci_phy_link_complete_evt(hdev, skb);
4094 break;
4095
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03004096 case HCI_EV_LOGICAL_LINK_COMPLETE:
4097 hci_loglink_complete_evt(hdev, skb);
4098 break;
4099
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02004100 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
4101 hci_disconn_loglink_complete_evt(hdev, skb);
4102 break;
4103
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02004104 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
4105 hci_disconn_phylink_complete_evt(hdev, skb);
4106 break;
4107
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02004108 case HCI_EV_NUM_COMP_BLOCKS:
4109 hci_num_comp_blocks_evt(hdev, skb);
4110 break;
4111
Marcel Holtmanna9de9242007-10-20 13:33:56 +02004112 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03004113 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004114 break;
4115 }
4116
4117 kfree_skb(skb);
4118 hdev->stat.evt_rx++;
4119}