blob: aae80531f8cefabcd1388a3457ef0a42b1ee5328 [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
Gustavo Padovan8c520a52012-05-23 04:04:22 -030027#include <linux/export.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <asm/unaligned.h>
29
30#include <net/bluetooth/bluetooth.h>
31#include <net/bluetooth/hci_core.h>
Mikel Astizf0d6a0e2012-08-09 09:52:30 +020032#include <net/bluetooth/mgmt.h>
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +030033#include <net/bluetooth/a2mp.h>
Andrei Emeltchenko903e4542012-09-27 17:26:09 +030034#include <net/bluetooth/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 Guedese6d465c2011-11-09 17:14:26 -030044 if (status) {
45 hci_dev_lock(hdev);
46 mgmt_stop_discovery_failed(hdev, status);
47 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020048 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030049 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Andre Guedes89352e72011-11-04 14:16:53 -030051 clear_bit(HCI_INQUIRY, &hdev->flags);
52
Johan Hedberg56e5cb82011-11-08 20:40:16 +020053 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020054 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020055 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010056
Johan Hedberg23bb5762010-12-21 23:01:27 +020057 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010058
Marcel Holtmanna9de9242007-10-20 13:33:56 +020059 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070060}
61
Andre Guedes4d934832012-03-21 00:03:35 -030062static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
63{
64 __u8 status = *((__u8 *) skb->data);
65
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030066 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesae854a72012-03-21 00:03:36 -030067
68 if (status)
69 return;
70
71 set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
Andre Guedes4d934832012-03-21 00:03:35 -030072}
73
Marcel Holtmanna9de9242007-10-20 13:33:56 +020074static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070075{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020076 __u8 status = *((__u8 *) skb->data);
77
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030078 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020079
80 if (status)
81 return;
82
Andre Guedesae854a72012-03-21 00:03:36 -030083 clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
84
Marcel Holtmanna9de9242007-10-20 13:33:56 +020085 hci_conn_check_pending(hdev);
86}
87
Gustavo Padovan807deac2012-05-17 00:36:24 -030088static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
89 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020090{
91 BT_DBG("%s", hdev->name);
92}
93
94static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
95{
96 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070098
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030099 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200101 if (rp->status)
102 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200104 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200106 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
107 if (conn) {
108 if (rp->role)
109 conn->link_mode &= ~HCI_LM_MASTER;
110 else
111 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200113
114 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115}
116
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200117static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
118{
119 struct hci_rp_read_link_policy *rp = (void *) skb->data;
120 struct hci_conn *conn;
121
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300122 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200123
124 if (rp->status)
125 return;
126
127 hci_dev_lock(hdev);
128
129 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
130 if (conn)
131 conn->link_policy = __le16_to_cpu(rp->policy);
132
133 hci_dev_unlock(hdev);
134}
135
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200136static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200138 struct hci_rp_write_link_policy *rp = (void *) skb->data;
139 struct hci_conn *conn;
140 void *sent;
141
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300142 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200143
144 if (rp->status)
145 return;
146
147 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
148 if (!sent)
149 return;
150
151 hci_dev_lock(hdev);
152
153 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200154 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700155 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200156
157 hci_dev_unlock(hdev);
158}
159
Gustavo Padovan807deac2012-05-17 00:36:24 -0300160static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
161 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200162{
163 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
164
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300165 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200166
167 if (rp->status)
168 return;
169
170 hdev->link_policy = __le16_to_cpu(rp->policy);
171}
172
Gustavo Padovan807deac2012-05-17 00:36:24 -0300173static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
174 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200175{
176 __u8 status = *((__u8 *) skb->data);
177 void *sent;
178
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300179 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200180
181 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
182 if (!sent)
183 return;
184
185 if (!status)
186 hdev->link_policy = get_unaligned_le16(sent);
187
Johan Hedberg23bb5762010-12-21 23:01:27 +0200188 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200189}
190
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200191static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
192{
193 __u8 status = *((__u8 *) skb->data);
194
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300195 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200196
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300197 clear_bit(HCI_RESET, &hdev->flags);
198
Johan Hedberg23bb5762010-12-21 23:01:27 +0200199 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300200
Johan Hedberga297e972012-02-21 17:55:47 +0200201 /* Reset all non-persistent flags */
Andre Guedesae854a72012-03-21 00:03:36 -0300202 hdev->dev_flags &= ~(BIT(HCI_LE_SCAN) | BIT(HCI_PENDING_CLASS) |
203 BIT(HCI_PERIODIC_INQ));
Andre Guedes69775ff2012-02-23 16:50:05 +0200204
205 hdev->discovery.state = DISCOVERY_STOPPED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200206}
207
208static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
209{
210 __u8 status = *((__u8 *) skb->data);
211 void *sent;
212
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300213 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200214
215 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
216 if (!sent)
217 return;
218
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200219 hci_dev_lock(hdev);
220
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200221 if (test_bit(HCI_MGMT, &hdev->dev_flags))
222 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200223 else if (!status)
224 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200225
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200226 hci_dev_unlock(hdev);
Johan Hedberg3159d382012-02-24 13:47:56 +0200227
228 hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200229}
230
231static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
232{
233 struct hci_rp_read_local_name *rp = (void *) skb->data;
234
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300235 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200236
237 if (rp->status)
238 return;
239
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200240 if (test_bit(HCI_SETUP, &hdev->dev_flags))
241 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200242}
243
244static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
245{
246 __u8 status = *((__u8 *) skb->data);
247 void *sent;
248
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300249 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200250
251 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
252 if (!sent)
253 return;
254
255 if (!status) {
256 __u8 param = *((__u8 *) sent);
257
258 if (param == AUTH_ENABLED)
259 set_bit(HCI_AUTH, &hdev->flags);
260 else
261 clear_bit(HCI_AUTH, &hdev->flags);
262 }
263
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200264 if (test_bit(HCI_MGMT, &hdev->dev_flags))
265 mgmt_auth_enable_complete(hdev, status);
266
Johan Hedberg23bb5762010-12-21 23:01:27 +0200267 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200268}
269
270static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
271{
272 __u8 status = *((__u8 *) skb->data);
273 void *sent;
274
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300275 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200276
277 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
278 if (!sent)
279 return;
280
281 if (!status) {
282 __u8 param = *((__u8 *) sent);
283
284 if (param)
285 set_bit(HCI_ENCRYPT, &hdev->flags);
286 else
287 clear_bit(HCI_ENCRYPT, &hdev->flags);
288 }
289
Johan Hedberg23bb5762010-12-21 23:01:27 +0200290 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200291}
292
293static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
294{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200295 __u8 param, status = *((__u8 *) skb->data);
296 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200297 void *sent;
298
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300299 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200300
301 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
302 if (!sent)
303 return;
304
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200305 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200306
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200307 hci_dev_lock(hdev);
308
Mikel Astizfa1bd912012-08-09 09:52:29 +0200309 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200310 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200311 hdev->discov_timeout = 0;
312 goto done;
313 }
314
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200315 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
316 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200317
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200318 if (param & SCAN_INQUIRY) {
319 set_bit(HCI_ISCAN, &hdev->flags);
320 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200321 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200322 if (hdev->discov_timeout > 0) {
323 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
324 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300325 to);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200326 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200327 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200328 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200329
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200330 if (param & SCAN_PAGE) {
331 set_bit(HCI_PSCAN, &hdev->flags);
332 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200333 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200334 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200335 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200336
337done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200338 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200339 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200340}
341
342static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
343{
344 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
345
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300346 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200347
348 if (rp->status)
349 return;
350
351 memcpy(hdev->dev_class, rp->dev_class, 3);
352
353 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300354 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200355}
356
357static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
358{
359 __u8 status = *((__u8 *) skb->data);
360 void *sent;
361
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300362 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200363
364 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
365 if (!sent)
366 return;
367
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100368 hci_dev_lock(hdev);
369
370 if (status == 0)
371 memcpy(hdev->dev_class, sent, 3);
372
373 if (test_bit(HCI_MGMT, &hdev->dev_flags))
374 mgmt_set_class_of_dev_complete(hdev, sent, status);
375
376 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200377}
378
379static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
380{
381 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200383
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300384 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200385
386 if (rp->status)
387 return;
388
389 setting = __le16_to_cpu(rp->voice_setting);
390
Marcel Holtmannf383f272008-07-14 20:13:47 +0200391 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200392 return;
393
394 hdev->voice_setting = setting;
395
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300396 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200397
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200398 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200399 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200400}
401
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300402static void hci_cc_write_voice_setting(struct hci_dev *hdev,
403 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200404{
405 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200406 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407 void *sent;
408
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300409 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410
Marcel Holtmannf383f272008-07-14 20:13:47 +0200411 if (status)
412 return;
413
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200414 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
415 if (!sent)
416 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417
Marcel Holtmannf383f272008-07-14 20:13:47 +0200418 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419
Marcel Holtmannf383f272008-07-14 20:13:47 +0200420 if (hdev->voice_setting == setting)
421 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422
Marcel Holtmannf383f272008-07-14 20:13:47 +0200423 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300425 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200426
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200427 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200428 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429}
430
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200431static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200433 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300435 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436
Johan Hedberg23bb5762010-12-21 23:01:27 +0200437 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438}
439
Marcel Holtmann333140b2008-07-14 20:13:48 +0200440static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
441{
442 __u8 status = *((__u8 *) skb->data);
443 void *sent;
444
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300445 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200446
Marcel Holtmann333140b2008-07-14 20:13:48 +0200447 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
448 if (!sent)
449 return;
450
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200451 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200452 mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status);
453 else if (!status) {
454 if (*((u8 *) sent))
455 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
456 else
457 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
458 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200459}
460
Johan Hedbergd5859e22011-01-25 01:19:58 +0200461static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
462{
Johan Hedberg976eb202012-10-24 21:12:01 +0300463 if (lmp_ext_inq_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200464 return 2;
465
Johan Hedberg976eb202012-10-24 21:12:01 +0300466 if (lmp_inq_rssi_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200467 return 1;
468
469 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -0300470 hdev->lmp_subver == 0x0757)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200471 return 1;
472
473 if (hdev->manufacturer == 15) {
474 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
475 return 1;
476 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
477 return 1;
478 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
479 return 1;
480 }
481
482 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -0300483 hdev->lmp_subver == 0x1805)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200484 return 1;
485
486 return 0;
487}
488
489static void hci_setup_inquiry_mode(struct hci_dev *hdev)
490{
491 u8 mode;
492
493 mode = hci_get_inquiry_mode(hdev);
494
495 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
496}
497
498static void hci_setup_event_mask(struct hci_dev *hdev)
499{
500 /* The second byte is 0xff instead of 0x9f (two reserved bits
501 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
502 * command otherwise */
503 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
504
Ville Tervo6de6c182011-05-27 11:16:21 +0300505 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
506 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200507 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300508 return;
509
Johan Hedberge1171e82012-10-19 20:57:45 +0300510 if (lmp_bredr_capable(hdev)) {
511 events[4] |= 0x01; /* Flow Specification Complete */
512 events[4] |= 0x02; /* Inquiry Result with RSSI */
513 events[4] |= 0x04; /* Read Remote Extended Features Complete */
514 events[5] |= 0x08; /* Synchronous Connection Complete */
515 events[5] |= 0x10; /* Synchronous Connection Changed */
516 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200517
Johan Hedberg976eb202012-10-24 21:12:01 +0300518 if (lmp_inq_rssi_capable(hdev))
Johan Hedberga24299e2012-04-26 09:47:46 +0300519 events[4] |= 0x02; /* Inquiry Result with RSSI */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200520
Andre Guedes999dcd12012-07-24 15:03:52 -0300521 if (lmp_sniffsubr_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200522 events[5] |= 0x20; /* Sniff Subrating */
523
Johan Hedberg976eb202012-10-24 21:12:01 +0300524 if (lmp_pause_enc_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200525 events[5] |= 0x80; /* Encryption Key Refresh Complete */
526
Johan Hedberg976eb202012-10-24 21:12:01 +0300527 if (lmp_ext_inq_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200528 events[5] |= 0x40; /* Extended Inquiry Result */
529
Andre Guedesc58e8102012-07-24 15:03:53 -0300530 if (lmp_no_flush_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200531 events[7] |= 0x01; /* Enhanced Flush Complete */
532
Johan Hedberg976eb202012-10-24 21:12:01 +0300533 if (lmp_lsto_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200534 events[6] |= 0x80; /* Link Supervision Timeout Changed */
535
Andre Guedes9a1a1992012-07-24 15:03:48 -0300536 if (lmp_ssp_capable(hdev)) {
Johan Hedbergd5859e22011-01-25 01:19:58 +0200537 events[6] |= 0x01; /* IO Capability Request */
538 events[6] |= 0x02; /* IO Capability Response */
539 events[6] |= 0x04; /* User Confirmation Request */
540 events[6] |= 0x08; /* User Passkey Request */
541 events[6] |= 0x10; /* Remote OOB Data Request */
542 events[6] |= 0x20; /* Simple Pairing Complete */
543 events[7] |= 0x04; /* User Passkey Notification */
544 events[7] |= 0x08; /* Keypress Notification */
545 events[7] |= 0x10; /* Remote Host Supported
546 * Features Notification */
547 }
548
Andre Guedesc383ddc2012-07-24 15:03:47 -0300549 if (lmp_le_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200550 events[7] |= 0x20; /* LE Meta-Event */
551
552 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
Johan Hedberge36b04c2012-10-19 20:57:47 +0300553
554 if (lmp_le_capable(hdev)) {
555 memset(events, 0, sizeof(events));
556 events[0] = 0x1f;
557 hci_send_cmd(hdev, HCI_OP_LE_SET_EVENT_MASK,
558 sizeof(events), events);
559 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200560}
561
Gustavo Padovan4611dfa2012-10-24 11:18:41 -0200562static void bredr_setup(struct hci_dev *hdev)
Johan Hedberge1171e82012-10-19 20:57:45 +0300563{
564 struct hci_cp_delete_stored_link_key cp;
565 __le16 param;
566 __u8 flt_type;
567
568 /* Read Buffer Size (ACL mtu, max pkt, etc.) */
569 hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
570
571 /* Read Class of Device */
572 hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
573
574 /* Read Local Name */
575 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
576
577 /* Read Voice Setting */
578 hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
579
580 /* Clear Event Filters */
581 flt_type = HCI_FLT_CLEAR_ALL;
582 hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
583
584 /* Connection accept timeout ~20 secs */
585 param = __constant_cpu_to_le16(0x7d00);
586 hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
587
588 bacpy(&cp.bdaddr, BDADDR_ANY);
589 cp.delete_all = 1;
590 hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
591}
592
Gustavo Padovan4611dfa2012-10-24 11:18:41 -0200593static void le_setup(struct hci_dev *hdev)
Johan Hedberge1171e82012-10-19 20:57:45 +0300594{
595 /* Read LE Buffer Size */
596 hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
Johan Hedberg8fa19092012-10-19 20:57:49 +0300597
598 /* Read LE Advertising Channel TX Power */
599 hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
Johan Hedberge1171e82012-10-19 20:57:45 +0300600}
601
Johan Hedbergd5859e22011-01-25 01:19:58 +0200602static void hci_setup(struct hci_dev *hdev)
603{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200604 if (hdev->dev_type != HCI_BREDR)
605 return;
606
Johan Hedberge1171e82012-10-19 20:57:45 +0300607 /* Read BD Address */
608 hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
609
610 if (lmp_bredr_capable(hdev))
Gustavo Padovan4611dfa2012-10-24 11:18:41 -0200611 bredr_setup(hdev);
Johan Hedberge1171e82012-10-19 20:57:45 +0300612
613 if (lmp_le_capable(hdev))
Gustavo Padovan4611dfa2012-10-24 11:18:41 -0200614 le_setup(hdev);
Johan Hedberge1171e82012-10-19 20:57:45 +0300615
Johan Hedbergd5859e22011-01-25 01:19:58 +0200616 hci_setup_event_mask(hdev);
617
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200618 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200619 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
620
Gustavo Padovan6d3c7302012-05-24 03:36:37 -0300621 if (lmp_ssp_capable(hdev)) {
Johan Hedberg54d04db2012-02-22 15:47:48 +0200622 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
623 u8 mode = 0x01;
624 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300625 sizeof(mode), &mode);
Johan Hedberg54d04db2012-02-22 15:47:48 +0200626 } else {
627 struct hci_cp_write_eir cp;
628
629 memset(hdev->eir, 0, sizeof(hdev->eir));
630 memset(&cp, 0, sizeof(cp));
631
632 hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
633 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200634 }
635
Johan Hedberg976eb202012-10-24 21:12:01 +0300636 if (lmp_inq_rssi_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200637 hci_setup_inquiry_mode(hdev);
638
Johan Hedberg976eb202012-10-24 21:12:01 +0300639 if (lmp_inq_tx_pwr_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200640 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300641
Johan Hedberg976eb202012-10-24 21:12:01 +0300642 if (lmp_ext_feat_capable(hdev)) {
Andre Guedes971e3a42011-06-30 19:20:52 -0300643 struct hci_cp_read_local_ext_features cp;
644
645 cp.page = 0x01;
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300646 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp),
647 &cp);
Andre Guedes971e3a42011-06-30 19:20:52 -0300648 }
Andre Guedese6100a22011-06-30 19:20:54 -0300649
Johan Hedberg47990ea2012-02-22 11:58:37 +0200650 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
651 u8 enable = 1;
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300652 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(enable),
653 &enable);
Johan Hedberg47990ea2012-02-22 11:58:37 +0200654 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200655}
656
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200657static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
658{
659 struct hci_rp_read_local_version *rp = (void *) skb->data;
660
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300661 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200662
663 if (rp->status)
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200664 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200665
666 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200667 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200668 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200669 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200670 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200671
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300672 BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300673 hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200674
675 if (test_bit(HCI_INIT, &hdev->flags))
676 hci_setup(hdev);
Andrei Emeltchenko28b8df72012-02-24 12:45:44 +0200677
678done:
679 hci_req_complete(hdev, HCI_OP_READ_LOCAL_VERSION, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200680}
681
682static void hci_setup_link_policy(struct hci_dev *hdev)
683{
Andrei Emeltchenko035100c2012-03-12 15:59:32 +0200684 struct hci_cp_write_def_link_policy cp;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200685 u16 link_policy = 0;
686
Andre Guedes9f92ebf2012-07-24 15:03:50 -0300687 if (lmp_rswitch_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200688 link_policy |= HCI_LP_RSWITCH;
Johan Hedberg976eb202012-10-24 21:12:01 +0300689 if (lmp_hold_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200690 link_policy |= HCI_LP_HOLD;
Andre Guedes6eded102012-07-24 15:03:51 -0300691 if (lmp_sniff_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200692 link_policy |= HCI_LP_SNIFF;
Johan Hedberg976eb202012-10-24 21:12:01 +0300693 if (lmp_park_capable(hdev))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200694 link_policy |= HCI_LP_PARK;
695
Andrei Emeltchenko035100c2012-03-12 15:59:32 +0200696 cp.policy = cpu_to_le16(link_policy);
697 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200698}
699
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300700static void hci_cc_read_local_commands(struct hci_dev *hdev,
701 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200702{
703 struct hci_rp_read_local_commands *rp = (void *) skb->data;
704
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300705 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200706
707 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200708 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200709
710 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200711
712 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
713 hci_setup_link_policy(hdev);
714
715done:
716 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200717}
718
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300719static void hci_cc_read_local_features(struct hci_dev *hdev,
720 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200721{
722 struct hci_rp_read_local_features *rp = (void *) skb->data;
723
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300724 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200725
726 if (rp->status)
727 return;
728
729 memcpy(hdev->features, rp->features, 8);
730
731 /* Adjust default settings according to features
732 * supported by device. */
733
734 if (hdev->features[0] & LMP_3SLOT)
735 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
736
737 if (hdev->features[0] & LMP_5SLOT)
738 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
739
740 if (hdev->features[1] & LMP_HV2) {
741 hdev->pkt_type |= (HCI_HV2);
742 hdev->esco_type |= (ESCO_HV2);
743 }
744
745 if (hdev->features[1] & LMP_HV3) {
746 hdev->pkt_type |= (HCI_HV3);
747 hdev->esco_type |= (ESCO_HV3);
748 }
749
Andre Guedes45db810f2012-07-24 15:03:49 -0300750 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200751 hdev->esco_type |= (ESCO_EV3);
752
753 if (hdev->features[4] & LMP_EV4)
754 hdev->esco_type |= (ESCO_EV4);
755
756 if (hdev->features[4] & LMP_EV5)
757 hdev->esco_type |= (ESCO_EV5);
758
Marcel Holtmannefc76882009-02-06 09:13:37 +0100759 if (hdev->features[5] & LMP_EDR_ESCO_2M)
760 hdev->esco_type |= (ESCO_2EV3);
761
762 if (hdev->features[5] & LMP_EDR_ESCO_3M)
763 hdev->esco_type |= (ESCO_3EV3);
764
765 if (hdev->features[5] & LMP_EDR_3S_ESCO)
766 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
767
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200768 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300769 hdev->features[0], hdev->features[1],
770 hdev->features[2], hdev->features[3],
771 hdev->features[4], hdev->features[5],
772 hdev->features[6], hdev->features[7]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200773}
774
Johan Hedberg8f984df2012-02-28 01:07:22 +0200775static void hci_set_le_support(struct hci_dev *hdev)
776{
777 struct hci_cp_write_le_host_supported cp;
778
779 memset(&cp, 0, sizeof(cp));
780
Marcel Holtmann9d428202012-05-03 07:12:31 +0200781 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
Johan Hedberg8f984df2012-02-28 01:07:22 +0200782 cp.le = 1;
Johan Hedberg976eb202012-10-24 21:12:01 +0300783 cp.simul = !!lmp_le_br_capable(hdev);
Johan Hedberg8f984df2012-02-28 01:07:22 +0200784 }
785
Johan Hedberg976eb202012-10-24 21:12:01 +0300786 if (cp.le != !!lmp_host_le_capable(hdev))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300787 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
788 &cp);
Johan Hedberg8f984df2012-02-28 01:07:22 +0200789}
790
Andre Guedes971e3a42011-06-30 19:20:52 -0300791static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300792 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300793{
794 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
795
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300796 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300797
798 if (rp->status)
Johan Hedberg8f984df2012-02-28 01:07:22 +0200799 goto done;
Andre Guedes971e3a42011-06-30 19:20:52 -0300800
Andre Guedesb5b32b62011-12-30 10:34:04 -0300801 switch (rp->page) {
802 case 0:
803 memcpy(hdev->features, rp->features, 8);
804 break;
805 case 1:
806 memcpy(hdev->host_features, rp->features, 8);
807 break;
808 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300809
Andre Guedesc383ddc2012-07-24 15:03:47 -0300810 if (test_bit(HCI_INIT, &hdev->flags) && lmp_le_capable(hdev))
Johan Hedberg8f984df2012-02-28 01:07:22 +0200811 hci_set_le_support(hdev);
812
813done:
Andre Guedes971e3a42011-06-30 19:20:52 -0300814 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
815}
816
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200817static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300818 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200819{
820 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
821
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300822 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200823
824 if (rp->status)
825 return;
826
827 hdev->flow_ctl_mode = rp->mode;
828
829 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
830}
831
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200832static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
833{
834 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
835
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300836 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200837
838 if (rp->status)
839 return;
840
841 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
842 hdev->sco_mtu = rp->sco_mtu;
843 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
844 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
845
846 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
847 hdev->sco_mtu = 64;
848 hdev->sco_pkts = 8;
849 }
850
851 hdev->acl_cnt = hdev->acl_pkts;
852 hdev->sco_cnt = hdev->sco_pkts;
853
Gustavo Padovan807deac2012-05-17 00:36:24 -0300854 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
855 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200856}
857
858static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
859{
860 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
861
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300862 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200863
864 if (!rp->status)
865 bacpy(&hdev->bdaddr, &rp->bdaddr);
866
Johan Hedberg23bb5762010-12-21 23:01:27 +0200867 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
868}
869
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200870static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300871 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200872{
873 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
874
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300875 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200876
877 if (rp->status)
878 return;
879
880 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
881 hdev->block_len = __le16_to_cpu(rp->block_len);
882 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
883
884 hdev->block_cnt = hdev->num_blocks;
885
886 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300887 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200888
889 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
890}
891
Johan Hedberg23bb5762010-12-21 23:01:27 +0200892static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
893{
894 __u8 status = *((__u8 *) skb->data);
895
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300896 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200897
898 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200899}
900
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300901static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300902 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300903{
904 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
905
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300906 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300907
908 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300909 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300910
911 hdev->amp_status = rp->amp_status;
912 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
913 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
914 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
915 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
916 hdev->amp_type = rp->amp_type;
917 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
918 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
919 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
920 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
921
922 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300923
924a2mp_rsp:
925 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300926}
927
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300928static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
929 struct sk_buff *skb)
930{
931 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
932 struct amp_assoc *assoc = &hdev->loc_assoc;
933 size_t rem_len, frag_len;
934
935 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
936
937 if (rp->status)
938 goto a2mp_rsp;
939
940 frag_len = skb->len - sizeof(*rp);
941 rem_len = __le16_to_cpu(rp->rem_len);
942
943 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300944 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300945
946 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
947 assoc->offset += frag_len;
948
949 /* Read other fragments */
950 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
951
952 return;
953 }
954
955 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
956 assoc->len = assoc->offset + rem_len;
957 assoc->offset = 0;
958
959a2mp_rsp:
960 /* Send A2MP Rsp when all fragments are received */
961 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300962 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300963}
964
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200965static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300966 struct sk_buff *skb)
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200967{
968 __u8 status = *((__u8 *) skb->data);
969
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300970 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200971
972 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
973}
974
Johan Hedbergd5859e22011-01-25 01:19:58 +0200975static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
976{
977 __u8 status = *((__u8 *) skb->data);
978
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300979 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200980
981 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
982}
983
984static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300985 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200986{
987 __u8 status = *((__u8 *) skb->data);
988
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300989 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200990
991 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
992}
993
994static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300995 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200996{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700997 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200998
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300999 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +02001000
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -07001001 if (!rp->status)
1002 hdev->inq_tx_power = rp->tx_power;
1003
1004 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +02001005}
1006
1007static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
1008{
1009 __u8 status = *((__u8 *) skb->data);
1010
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001011 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedbergd5859e22011-01-25 01:19:58 +02001012
1013 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
1014}
1015
Johan Hedberg980e1a52011-01-22 06:10:07 +02001016static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
1017{
1018 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
1019 struct hci_cp_pin_code_reply *cp;
1020 struct hci_conn *conn;
1021
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001022 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +02001023
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001024 hci_dev_lock(hdev);
1025
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001026 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001027 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +02001028
Mikel Astizfa1bd912012-08-09 09:52:29 +02001029 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001030 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +02001031
1032 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
1033 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001034 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +02001035
1036 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1037 if (conn)
1038 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001039
1040unlock:
1041 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +02001042}
1043
1044static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1045{
1046 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
1047
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001048 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +02001049
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001050 hci_dev_lock(hdev);
1051
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001052 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001053 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001054 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001055
1056 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +02001057}
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001058
Ville Tervo6ed58ec2011-02-10 22:38:48 -03001059static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
1060 struct sk_buff *skb)
1061{
1062 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
1063
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001064 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -03001065
1066 if (rp->status)
1067 return;
1068
1069 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
1070 hdev->le_pkts = rp->le_max_pkt;
1071
1072 hdev->le_cnt = hdev->le_pkts;
1073
1074 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
1075
1076 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
1077}
Johan Hedberg980e1a52011-01-22 06:10:07 +02001078
Johan Hedberg8fa19092012-10-19 20:57:49 +03001079static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
1080 struct sk_buff *skb)
1081{
1082 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
1083
1084 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
1085
1086 if (!rp->status)
1087 hdev->adv_tx_power = rp->tx_power;
1088
1089 hci_req_complete(hdev, HCI_OP_LE_READ_ADV_TX_POWER, rp->status);
1090}
1091
Johan Hedberge36b04c2012-10-19 20:57:47 +03001092static void hci_cc_le_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
1093{
1094 __u8 status = *((__u8 *) skb->data);
1095
1096 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1097
1098 hci_req_complete(hdev, HCI_OP_LE_SET_EVENT_MASK, status);
1099}
1100
Johan Hedberga5c29682011-02-19 12:05:57 -03001101static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
1102{
1103 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1104
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001105 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -03001106
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001107 hci_dev_lock(hdev);
1108
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001109 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001110 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
1111 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001112
1113 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -03001114}
1115
1116static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001117 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03001118{
1119 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1120
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001121 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -03001122
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001123 hci_dev_lock(hdev);
1124
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001125 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001126 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001127 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001128
1129 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -03001130}
1131
Brian Gix1143d452011-11-23 08:28:34 -08001132static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
1133{
1134 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1135
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001136 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001137
1138 hci_dev_lock(hdev);
1139
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001140 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02001141 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001142 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001143
1144 hci_dev_unlock(hdev);
1145}
1146
1147static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001148 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08001149{
1150 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1151
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001152 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001153
1154 hci_dev_lock(hdev);
1155
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001156 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001157 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001158 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001159
1160 hci_dev_unlock(hdev);
1161}
1162
Szymon Jancc35938b2011-03-22 13:12:21 +01001163static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001164 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +01001165{
1166 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1167
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001168 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +01001169
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001170 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001171 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001172 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001173 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001174}
1175
Andre Guedes07f7fa52011-12-02 21:13:31 +09001176static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1177{
1178 __u8 status = *((__u8 *) skb->data);
1179
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001180 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001181
1182 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001183
1184 if (status) {
1185 hci_dev_lock(hdev);
1186 mgmt_start_discovery_failed(hdev, status);
1187 hci_dev_unlock(hdev);
1188 return;
1189 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001190}
1191
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001192static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001193 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001194{
1195 struct hci_cp_le_set_scan_enable *cp;
1196 __u8 status = *((__u8 *) skb->data);
1197
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001198 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001199
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001200 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1201 if (!cp)
1202 return;
1203
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001204 switch (cp->enable) {
1205 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001206 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1207
Andre Guedes3fd24152012-02-03 17:48:01 -03001208 if (status) {
1209 hci_dev_lock(hdev);
1210 mgmt_start_discovery_failed(hdev, status);
1211 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001212 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001213 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001214
Andre Guedesd23264a2011-11-25 20:53:38 -03001215 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1216
Andre Guedesa8f13c82011-09-09 18:56:24 -03001217 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001218 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001219 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001220 break;
1221
1222 case LE_SCANNING_DISABLED:
Andre Guedesc9ecc482012-03-15 16:52:08 -03001223 if (status) {
1224 hci_dev_lock(hdev);
1225 mgmt_stop_discovery_failed(hdev, status);
1226 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001227 return;
Andre Guedesc9ecc482012-03-15 16:52:08 -03001228 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001229
Andre Guedesd23264a2011-11-25 20:53:38 -03001230 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1231
Andre Guedesbc3dd332012-03-06 19:37:06 -03001232 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED &&
1233 hdev->discovery.state == DISCOVERY_FINDING) {
Andre Guedes5e0452c2012-02-17 20:39:38 -03001234 mgmt_interleaved_discovery(hdev);
1235 } else {
1236 hci_dev_lock(hdev);
1237 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1238 hci_dev_unlock(hdev);
1239 }
1240
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001241 break;
1242
1243 default:
1244 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1245 break;
Andre Guedes35815082011-05-26 16:23:53 -03001246 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001247}
1248
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001249static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1250{
1251 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1252
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001253 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001254
1255 if (rp->status)
1256 return;
1257
1258 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1259}
1260
1261static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1262{
1263 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1264
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001265 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001266
1267 if (rp->status)
1268 return;
1269
1270 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1271}
1272
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001273static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1274 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -03001275{
Johan Hedberg06199cf2012-02-22 16:37:11 +02001276 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001277 __u8 status = *((__u8 *) skb->data);
1278
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001279 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001280
Johan Hedberg06199cf2012-02-22 16:37:11 +02001281 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +02001282 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -03001283 return;
1284
Johan Hedberg8f984df2012-02-28 01:07:22 +02001285 if (!status) {
1286 if (sent->le)
1287 hdev->host_features[0] |= LMP_HOST_LE;
1288 else
1289 hdev->host_features[0] &= ~LMP_HOST_LE;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001290
1291 if (sent->simul)
1292 hdev->host_features[0] |= LMP_HOST_LE_BREDR;
1293 else
1294 hdev->host_features[0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001295 }
1296
1297 if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001298 !test_bit(HCI_INIT, &hdev->flags))
Johan Hedberg8f984df2012-02-28 01:07:22 +02001299 mgmt_le_enable_complete(hdev, sent->le, status);
1300
1301 hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status);
Andre Guedesf9b49302011-06-30 19:20:53 -03001302}
1303
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001304static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1305 struct sk_buff *skb)
1306{
1307 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1308
1309 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1310 hdev->name, rp->status, rp->phy_handle);
1311
1312 if (rp->status)
1313 return;
1314
1315 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1316}
1317
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001318static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001319{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001320 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001321
1322 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001323 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001324 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001325 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001326 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001327 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001328 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001329 return;
1330 }
1331
Andre Guedes89352e72011-11-04 14:16:53 -03001332 set_bit(HCI_INQUIRY, &hdev->flags);
1333
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001334 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001335 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001336 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001337}
1338
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001339static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001341 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001344 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001345
1346 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347 if (!cp)
1348 return;
1349
1350 hci_dev_lock(hdev);
1351
1352 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1353
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001354 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355
1356 if (status) {
1357 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001358 if (status != 0x0c || conn->attempt > 2) {
1359 conn->state = BT_CLOSED;
1360 hci_proto_connect_cfm(conn, status);
1361 hci_conn_del(conn);
1362 } else
1363 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364 }
1365 } else {
1366 if (!conn) {
1367 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1368 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001369 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370 conn->link_mode |= HCI_LM_MASTER;
1371 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001372 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373 }
1374 }
1375
1376 hci_dev_unlock(hdev);
1377}
1378
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001379static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001381 struct hci_cp_add_sco *cp;
1382 struct hci_conn *acl, *sco;
1383 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001385 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001386
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001387 if (!status)
1388 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001390 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1391 if (!cp)
1392 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001394 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001396 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001397
1398 hci_dev_lock(hdev);
1399
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001400 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001401 if (acl) {
1402 sco = acl->link;
1403 if (sco) {
1404 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001405
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001406 hci_proto_connect_cfm(sco, status);
1407 hci_conn_del(sco);
1408 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001409 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001410
1411 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412}
1413
Marcel Holtmannf8558552008-07-14 20:13:49 +02001414static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1415{
1416 struct hci_cp_auth_requested *cp;
1417 struct hci_conn *conn;
1418
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001419 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001420
1421 if (!status)
1422 return;
1423
1424 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1425 if (!cp)
1426 return;
1427
1428 hci_dev_lock(hdev);
1429
1430 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1431 if (conn) {
1432 if (conn->state == BT_CONFIG) {
1433 hci_proto_connect_cfm(conn, status);
1434 hci_conn_put(conn);
1435 }
1436 }
1437
1438 hci_dev_unlock(hdev);
1439}
1440
1441static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1442{
1443 struct hci_cp_set_conn_encrypt *cp;
1444 struct hci_conn *conn;
1445
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001446 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001447
1448 if (!status)
1449 return;
1450
1451 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1452 if (!cp)
1453 return;
1454
1455 hci_dev_lock(hdev);
1456
1457 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1458 if (conn) {
1459 if (conn->state == BT_CONFIG) {
1460 hci_proto_connect_cfm(conn, status);
1461 hci_conn_put(conn);
1462 }
1463 }
1464
1465 hci_dev_unlock(hdev);
1466}
1467
Johan Hedberg127178d2010-11-18 22:22:29 +02001468static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001469 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001470{
Johan Hedberg392599b2010-11-18 22:22:28 +02001471 if (conn->state != BT_CONFIG || !conn->out)
1472 return 0;
1473
Johan Hedberg765c2a92011-01-19 12:06:52 +05301474 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001475 return 0;
1476
1477 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001478 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001479 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1480 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001481 return 0;
1482
Johan Hedberg392599b2010-11-18 22:22:28 +02001483 return 1;
1484}
1485
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001486static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001487 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001488{
1489 struct hci_cp_remote_name_req cp;
1490
1491 memset(&cp, 0, sizeof(cp));
1492
1493 bacpy(&cp.bdaddr, &e->data.bdaddr);
1494 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1495 cp.pscan_mode = e->data.pscan_mode;
1496 cp.clock_offset = e->data.clock_offset;
1497
1498 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1499}
1500
Johan Hedbergb644ba32012-01-17 21:48:47 +02001501static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001502{
1503 struct discovery_state *discov = &hdev->discovery;
1504 struct inquiry_entry *e;
1505
Johan Hedbergb644ba32012-01-17 21:48:47 +02001506 if (list_empty(&discov->resolve))
1507 return false;
1508
1509 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001510 if (!e)
1511 return false;
1512
Johan Hedbergb644ba32012-01-17 21:48:47 +02001513 if (hci_resolve_name(hdev, e) == 0) {
1514 e->name_state = NAME_PENDING;
1515 return true;
1516 }
1517
1518 return false;
1519}
1520
1521static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001522 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001523{
1524 struct discovery_state *discov = &hdev->discovery;
1525 struct inquiry_entry *e;
1526
1527 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001528 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1529 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001530
1531 if (discov->state == DISCOVERY_STOPPED)
1532 return;
1533
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001534 if (discov->state == DISCOVERY_STOPPING)
1535 goto discov_complete;
1536
1537 if (discov->state != DISCOVERY_RESOLVING)
1538 return;
1539
1540 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001541 /* If the device was not found in a list of found devices names of which
1542 * are pending. there is no need to continue resolving a next name as it
1543 * will be done upon receiving another Remote Name Request Complete
1544 * Event */
1545 if (!e)
1546 return;
1547
1548 list_del(&e->list);
1549 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001550 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001551 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1552 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001553 } else {
1554 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001555 }
1556
Johan Hedbergb644ba32012-01-17 21:48:47 +02001557 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001558 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001559
1560discov_complete:
1561 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1562}
1563
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001564static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1565{
Johan Hedberg127178d2010-11-18 22:22:29 +02001566 struct hci_cp_remote_name_req *cp;
1567 struct hci_conn *conn;
1568
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001569 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001570
1571 /* If successful wait for the name req complete event before
1572 * checking for the need to do authentication */
1573 if (!status)
1574 return;
1575
1576 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1577 if (!cp)
1578 return;
1579
1580 hci_dev_lock(hdev);
1581
1582 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001583
1584 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1585 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1586
Johan Hedberg79c6c702011-04-28 11:28:55 -07001587 if (!conn)
1588 goto unlock;
1589
1590 if (!hci_outgoing_auth_needed(hdev, conn))
1591 goto unlock;
1592
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001593 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001594 struct hci_cp_auth_requested cp;
1595 cp.handle = __cpu_to_le16(conn->handle);
1596 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1597 }
1598
Johan Hedberg79c6c702011-04-28 11:28:55 -07001599unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001600 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001601}
1602
Marcel Holtmann769be972008-07-14 20:13:49 +02001603static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1604{
1605 struct hci_cp_read_remote_features *cp;
1606 struct hci_conn *conn;
1607
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001608 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001609
1610 if (!status)
1611 return;
1612
1613 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1614 if (!cp)
1615 return;
1616
1617 hci_dev_lock(hdev);
1618
1619 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1620 if (conn) {
1621 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001622 hci_proto_connect_cfm(conn, status);
1623 hci_conn_put(conn);
1624 }
1625 }
1626
1627 hci_dev_unlock(hdev);
1628}
1629
1630static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1631{
1632 struct hci_cp_read_remote_ext_features *cp;
1633 struct hci_conn *conn;
1634
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001635 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001636
1637 if (!status)
1638 return;
1639
1640 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1641 if (!cp)
1642 return;
1643
1644 hci_dev_lock(hdev);
1645
1646 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1647 if (conn) {
1648 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001649 hci_proto_connect_cfm(conn, status);
1650 hci_conn_put(conn);
1651 }
1652 }
1653
1654 hci_dev_unlock(hdev);
1655}
1656
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001657static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1658{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001659 struct hci_cp_setup_sync_conn *cp;
1660 struct hci_conn *acl, *sco;
1661 __u16 handle;
1662
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001663 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001664
1665 if (!status)
1666 return;
1667
1668 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1669 if (!cp)
1670 return;
1671
1672 handle = __le16_to_cpu(cp->handle);
1673
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001674 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001675
1676 hci_dev_lock(hdev);
1677
1678 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001679 if (acl) {
1680 sco = acl->link;
1681 if (sco) {
1682 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001683
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001684 hci_proto_connect_cfm(sco, status);
1685 hci_conn_del(sco);
1686 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001687 }
1688
1689 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001690}
1691
1692static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1693{
1694 struct hci_cp_sniff_mode *cp;
1695 struct hci_conn *conn;
1696
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001697 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001698
1699 if (!status)
1700 return;
1701
1702 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1703 if (!cp)
1704 return;
1705
1706 hci_dev_lock(hdev);
1707
1708 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001709 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001710 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001711
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001712 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001713 hci_sco_setup(conn, status);
1714 }
1715
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001716 hci_dev_unlock(hdev);
1717}
1718
1719static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1720{
1721 struct hci_cp_exit_sniff_mode *cp;
1722 struct hci_conn *conn;
1723
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001724 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001725
1726 if (!status)
1727 return;
1728
1729 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1730 if (!cp)
1731 return;
1732
1733 hci_dev_lock(hdev);
1734
1735 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001736 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001737 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001738
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001739 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001740 hci_sco_setup(conn, status);
1741 }
1742
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001743 hci_dev_unlock(hdev);
1744}
1745
Johan Hedberg88c3df12012-02-09 14:27:38 +02001746static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1747{
1748 struct hci_cp_disconnect *cp;
1749 struct hci_conn *conn;
1750
1751 if (!status)
1752 return;
1753
1754 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1755 if (!cp)
1756 return;
1757
1758 hci_dev_lock(hdev);
1759
1760 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1761 if (conn)
1762 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001763 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001764
1765 hci_dev_unlock(hdev);
1766}
1767
Ville Tervofcd89c02011-02-10 22:38:47 -03001768static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1769{
Ville Tervofcd89c02011-02-10 22:38:47 -03001770 struct hci_conn *conn;
1771
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001772 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Ville Tervofcd89c02011-02-10 22:38:47 -03001773
Ville Tervofcd89c02011-02-10 22:38:47 -03001774 if (status) {
Andre Guedesf00a06a2012-07-27 15:10:13 -03001775 hci_dev_lock(hdev);
Ville Tervofcd89c02011-02-10 22:38:47 -03001776
Andre Guedes0c95ab72012-07-27 15:10:14 -03001777 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001778 if (!conn) {
1779 hci_dev_unlock(hdev);
1780 return;
1781 }
1782
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001783 BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001784
1785 conn->state = BT_CLOSED;
Andre Guedes0c95ab72012-07-27 15:10:14 -03001786 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Andre Guedesf00a06a2012-07-27 15:10:13 -03001787 conn->dst_type, status);
1788 hci_proto_connect_cfm(conn, status);
1789 hci_conn_del(conn);
1790
1791 hci_dev_unlock(hdev);
1792 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001793}
1794
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001795static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1796{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001797 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001798}
1799
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001800static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1801{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001802 struct hci_cp_create_phy_link *cp;
1803
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001804 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001805
1806 if (status)
1807 return;
1808
1809 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1810 if (!cp)
1811 return;
1812
1813 amp_write_remote_assoc(hdev, cp->phy_handle);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001814}
1815
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001816static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1817{
1818 struct hci_cp_accept_phy_link *cp;
1819
1820 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1821
1822 if (status)
1823 return;
1824
1825 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1826 if (!cp)
1827 return;
1828
1829 amp_write_remote_assoc(hdev, cp->phy_handle);
1830}
1831
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001832static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001833{
1834 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001835 struct discovery_state *discov = &hdev->discovery;
1836 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001837
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001838 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001839
Johan Hedberg23bb5762010-12-21 23:01:27 +02001840 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001841
1842 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001843
1844 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1845 return;
1846
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001847 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001848 return;
1849
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001850 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001851
Andre Guedes343f9352012-02-17 20:39:37 -03001852 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001853 goto unlock;
1854
1855 if (list_empty(&discov->resolve)) {
1856 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1857 goto unlock;
1858 }
1859
1860 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1861 if (e && hci_resolve_name(hdev, e) == 0) {
1862 e->name_state = NAME_PENDING;
1863 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1864 } else {
1865 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1866 }
1867
1868unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001869 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001870}
1871
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001872static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001874 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001875 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876 int num_rsp = *((__u8 *) skb->data);
1877
1878 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1879
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001880 if (!num_rsp)
1881 return;
1882
Andre Guedes1519cc12012-03-21 00:03:38 -03001883 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1884 return;
1885
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001887
Johan Hedberge17acd42011-03-30 23:57:16 +03001888 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001889 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001890
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891 bacpy(&data.bdaddr, &info->bdaddr);
1892 data.pscan_rep_mode = info->pscan_rep_mode;
1893 data.pscan_period_mode = info->pscan_period_mode;
1894 data.pscan_mode = info->pscan_mode;
1895 memcpy(data.dev_class, info->dev_class, 3);
1896 data.clock_offset = info->clock_offset;
1897 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001898 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001899
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001900 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001901 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001902 info->dev_class, 0, !name_known, ssp, NULL,
1903 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001905
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906 hci_dev_unlock(hdev);
1907}
1908
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001909static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001911 struct hci_ev_conn_complete *ev = (void *) skb->data;
1912 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001914 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001915
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001917
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001918 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001919 if (!conn) {
1920 if (ev->link_type != SCO_LINK)
1921 goto unlock;
1922
1923 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1924 if (!conn)
1925 goto unlock;
1926
1927 conn->type = SCO_LINK;
1928 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001929
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001930 if (!ev->status) {
1931 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001932
1933 if (conn->type == ACL_LINK) {
1934 conn->state = BT_CONFIG;
1935 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001936
1937 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1938 !hci_find_link_key(hdev, &ev->bdaddr))
1939 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1940 else
1941 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001942 } else
1943 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001944
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001945 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001946 hci_conn_add_sysfs(conn);
1947
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001948 if (test_bit(HCI_AUTH, &hdev->flags))
1949 conn->link_mode |= HCI_LM_AUTH;
1950
1951 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1952 conn->link_mode |= HCI_LM_ENCRYPT;
1953
1954 /* Get remote features */
1955 if (conn->type == ACL_LINK) {
1956 struct hci_cp_read_remote_features cp;
1957 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001958 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001959 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001960 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001961
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001962 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001963 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001964 struct hci_cp_change_conn_ptype cp;
1965 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001966 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001967 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1968 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001969 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001970 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001971 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001972 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001973 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001974 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001975 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001976
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001977 if (conn->type == ACL_LINK)
1978 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001979
Marcel Holtmann769be972008-07-14 20:13:49 +02001980 if (ev->status) {
1981 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001982 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001983 } else if (ev->link_type != ACL_LINK)
1984 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001985
1986unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001988
1989 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001990}
1991
Gustavo Padovan6039aa732012-05-23 04:04:18 -03001992static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001993{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001994 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001995 int mask = hdev->link_mode;
1996
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001997 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001998 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999
2000 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
2001
Szymon Janc138d22e2011-02-17 16:44:23 +01002002 if ((mask & HCI_LM_ACCEPT) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002003 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02002005 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007
2008 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002009
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002010 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2011 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02002012 memcpy(ie->data.dev_class, ev->dev_class, 3);
2013
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002014 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
2015 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002016 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002017 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
2018 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03002019 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020 hci_dev_unlock(hdev);
2021 return;
2022 }
2023 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002024
Linus Torvalds1da177e2005-04-16 15:20:36 -07002025 memcpy(conn->dev_class, ev->dev_class, 3);
2026 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002027
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028 hci_dev_unlock(hdev);
2029
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002030 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
2031 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002032
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002033 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002034
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002035 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
2036 cp.role = 0x00; /* Become master */
2037 else
2038 cp.role = 0x01; /* Remain slave */
2039
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002040 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
2041 &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002042 } else {
2043 struct hci_cp_accept_sync_conn_req cp;
2044
2045 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002046 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002047
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03002048 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
2049 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
2050 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002051 cp.content_format = cpu_to_le16(hdev->voice_setting);
2052 cp.retrans_effort = 0xff;
2053
2054 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002055 sizeof(cp), &cp);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002056 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002057 } else {
2058 /* Connection rejected */
2059 struct hci_cp_reject_conn_req cp;
2060
2061 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002062 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002063 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064 }
2065}
2066
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02002067static u8 hci_to_mgmt_reason(u8 err)
2068{
2069 switch (err) {
2070 case HCI_ERROR_CONNECTION_TIMEOUT:
2071 return MGMT_DEV_DISCONN_TIMEOUT;
2072 case HCI_ERROR_REMOTE_USER_TERM:
2073 case HCI_ERROR_REMOTE_LOW_RESOURCES:
2074 case HCI_ERROR_REMOTE_POWER_OFF:
2075 return MGMT_DEV_DISCONN_REMOTE;
2076 case HCI_ERROR_LOCAL_HOST_TERM:
2077 return MGMT_DEV_DISCONN_LOCAL_HOST;
2078 default:
2079 return MGMT_DEV_DISCONN_UNKNOWN;
2080 }
2081}
2082
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002083static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002084{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002085 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002086 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002088 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002089
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090 hci_dev_lock(hdev);
2091
Marcel Holtmann04837f62006-07-03 10:02:33 +02002092 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02002093 if (!conn)
2094 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002095
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002096 if (ev->status == 0)
2097 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098
Johan Hedbergb644ba32012-01-17 21:48:47 +02002099 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002100 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02002101 if (ev->status) {
Johan Hedberg88c3df12012-02-09 14:27:38 +02002102 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002103 conn->dst_type, ev->status);
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02002104 } else {
2105 u8 reason = hci_to_mgmt_reason(ev->reason);
2106
Johan Hedbergafc747a2012-01-15 18:11:07 +02002107 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02002108 conn->dst_type, reason);
2109 }
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002110 }
Johan Hedbergf7520542011-01-20 12:34:39 +02002111
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002112 if (ev->status == 0) {
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05302113 if (conn->type == ACL_LINK && conn->flush_key)
2114 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02002115 hci_proto_disconn_cfm(conn, ev->reason);
2116 hci_conn_del(conn);
2117 }
Johan Hedbergf7520542011-01-20 12:34:39 +02002118
2119unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120 hci_dev_unlock(hdev);
2121}
2122
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002123static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002124{
2125 struct hci_ev_auth_complete *ev = (void *) skb->data;
2126 struct hci_conn *conn;
2127
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002128 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002129
2130 hci_dev_lock(hdev);
2131
2132 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002133 if (!conn)
2134 goto unlock;
2135
2136 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002137 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002138 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002139 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03002140 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002141 conn->link_mode |= HCI_LM_AUTH;
2142 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03002143 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002144 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02002145 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002146 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002147 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002148
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002149 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
2150 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002151
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002152 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02002153 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002154 struct hci_cp_set_conn_encrypt cp;
2155 cp.handle = ev->handle;
2156 cp.encrypt = 0x01;
2157 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002158 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002159 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002160 conn->state = BT_CONNECTED;
2161 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002162 hci_conn_put(conn);
2163 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002164 } else {
2165 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002166
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002167 hci_conn_hold(conn);
2168 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
2169 hci_conn_put(conn);
2170 }
2171
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002172 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002173 if (!ev->status) {
2174 struct hci_cp_set_conn_encrypt cp;
2175 cp.handle = ev->handle;
2176 cp.encrypt = 0x01;
2177 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03002178 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002179 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002180 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002181 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002182 }
2183 }
2184
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02002185unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002186 hci_dev_unlock(hdev);
2187}
2188
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002189static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002190{
Johan Hedberg127178d2010-11-18 22:22:29 +02002191 struct hci_ev_remote_name *ev = (void *) skb->data;
2192 struct hci_conn *conn;
2193
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002194 BT_DBG("%s", hdev->name);
2195
2196 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02002197
2198 hci_dev_lock(hdev);
2199
2200 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002201
2202 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
2203 goto check_auth;
2204
2205 if (ev->status == 0)
2206 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002207 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02002208 else
2209 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
2210
2211check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07002212 if (!conn)
2213 goto unlock;
2214
2215 if (!hci_outgoing_auth_needed(hdev, conn))
2216 goto unlock;
2217
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002218 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002219 struct hci_cp_auth_requested cp;
2220 cp.handle = __cpu_to_le16(conn->handle);
2221 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2222 }
2223
Johan Hedberg79c6c702011-04-28 11:28:55 -07002224unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002225 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002226}
2227
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002228static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002229{
2230 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2231 struct hci_conn *conn;
2232
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002233 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002234
2235 hci_dev_lock(hdev);
2236
2237 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2238 if (conn) {
2239 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002240 if (ev->encrypt) {
2241 /* Encryption implies authentication */
2242 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002243 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002244 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002245 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002246 conn->link_mode &= ~HCI_LM_ENCRYPT;
2247 }
2248
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002249 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002250
Gustavo Padovana7d77232012-05-13 03:20:07 -03002251 if (ev->status && conn->state == BT_CONNECTED) {
Gustavo Padovand839c812012-05-16 12:17:12 -03002252 hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE);
Gustavo Padovana7d77232012-05-13 03:20:07 -03002253 hci_conn_put(conn);
2254 goto unlock;
2255 }
2256
Marcel Holtmannf8558552008-07-14 20:13:49 +02002257 if (conn->state == BT_CONFIG) {
2258 if (!ev->status)
2259 conn->state = BT_CONNECTED;
2260
2261 hci_proto_connect_cfm(conn, ev->status);
2262 hci_conn_put(conn);
2263 } else
2264 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002265 }
2266
Gustavo Padovana7d77232012-05-13 03:20:07 -03002267unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002268 hci_dev_unlock(hdev);
2269}
2270
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002271static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2272 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002273{
2274 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2275 struct hci_conn *conn;
2276
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002277 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002278
2279 hci_dev_lock(hdev);
2280
2281 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2282 if (conn) {
2283 if (!ev->status)
2284 conn->link_mode |= HCI_LM_SECURE;
2285
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002286 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002287
2288 hci_key_change_cfm(conn, ev->status);
2289 }
2290
2291 hci_dev_unlock(hdev);
2292}
2293
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002294static void hci_remote_features_evt(struct hci_dev *hdev,
2295 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002296{
2297 struct hci_ev_remote_features *ev = (void *) skb->data;
2298 struct hci_conn *conn;
2299
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002300 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002301
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002302 hci_dev_lock(hdev);
2303
2304 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002305 if (!conn)
2306 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002307
Johan Hedbergccd556f2010-11-10 17:11:51 +02002308 if (!ev->status)
2309 memcpy(conn->features, ev->features, 8);
2310
2311 if (conn->state != BT_CONFIG)
2312 goto unlock;
2313
2314 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2315 struct hci_cp_read_remote_ext_features cp;
2316 cp.handle = ev->handle;
2317 cp.page = 0x01;
2318 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002319 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002320 goto unlock;
2321 }
2322
Johan Hedberg671267b2012-05-12 16:11:50 -03002323 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002324 struct hci_cp_remote_name_req cp;
2325 memset(&cp, 0, sizeof(cp));
2326 bacpy(&cp.bdaddr, &conn->dst);
2327 cp.pscan_rep_mode = 0x02;
2328 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002329 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2330 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002331 conn->dst_type, 0, NULL, 0,
2332 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002333
Johan Hedberg127178d2010-11-18 22:22:29 +02002334 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002335 conn->state = BT_CONNECTED;
2336 hci_proto_connect_cfm(conn, ev->status);
2337 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002338 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002339
Johan Hedbergccd556f2010-11-10 17:11:51 +02002340unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002341 hci_dev_unlock(hdev);
2342}
2343
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002344static void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002345{
2346 BT_DBG("%s", hdev->name);
2347}
2348
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002349static void hci_qos_setup_complete_evt(struct hci_dev *hdev,
2350 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002351{
2352 BT_DBG("%s", hdev->name);
2353}
2354
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002355static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002356{
2357 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2358 __u16 opcode;
2359
2360 skb_pull(skb, sizeof(*ev));
2361
2362 opcode = __le16_to_cpu(ev->opcode);
2363
2364 switch (opcode) {
2365 case HCI_OP_INQUIRY_CANCEL:
2366 hci_cc_inquiry_cancel(hdev, skb);
2367 break;
2368
Andre Guedes4d934832012-03-21 00:03:35 -03002369 case HCI_OP_PERIODIC_INQ:
2370 hci_cc_periodic_inq(hdev, skb);
2371 break;
2372
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002373 case HCI_OP_EXIT_PERIODIC_INQ:
2374 hci_cc_exit_periodic_inq(hdev, skb);
2375 break;
2376
2377 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2378 hci_cc_remote_name_req_cancel(hdev, skb);
2379 break;
2380
2381 case HCI_OP_ROLE_DISCOVERY:
2382 hci_cc_role_discovery(hdev, skb);
2383 break;
2384
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002385 case HCI_OP_READ_LINK_POLICY:
2386 hci_cc_read_link_policy(hdev, skb);
2387 break;
2388
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002389 case HCI_OP_WRITE_LINK_POLICY:
2390 hci_cc_write_link_policy(hdev, skb);
2391 break;
2392
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002393 case HCI_OP_READ_DEF_LINK_POLICY:
2394 hci_cc_read_def_link_policy(hdev, skb);
2395 break;
2396
2397 case HCI_OP_WRITE_DEF_LINK_POLICY:
2398 hci_cc_write_def_link_policy(hdev, skb);
2399 break;
2400
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002401 case HCI_OP_RESET:
2402 hci_cc_reset(hdev, skb);
2403 break;
2404
2405 case HCI_OP_WRITE_LOCAL_NAME:
2406 hci_cc_write_local_name(hdev, skb);
2407 break;
2408
2409 case HCI_OP_READ_LOCAL_NAME:
2410 hci_cc_read_local_name(hdev, skb);
2411 break;
2412
2413 case HCI_OP_WRITE_AUTH_ENABLE:
2414 hci_cc_write_auth_enable(hdev, skb);
2415 break;
2416
2417 case HCI_OP_WRITE_ENCRYPT_MODE:
2418 hci_cc_write_encrypt_mode(hdev, skb);
2419 break;
2420
2421 case HCI_OP_WRITE_SCAN_ENABLE:
2422 hci_cc_write_scan_enable(hdev, skb);
2423 break;
2424
2425 case HCI_OP_READ_CLASS_OF_DEV:
2426 hci_cc_read_class_of_dev(hdev, skb);
2427 break;
2428
2429 case HCI_OP_WRITE_CLASS_OF_DEV:
2430 hci_cc_write_class_of_dev(hdev, skb);
2431 break;
2432
2433 case HCI_OP_READ_VOICE_SETTING:
2434 hci_cc_read_voice_setting(hdev, skb);
2435 break;
2436
2437 case HCI_OP_WRITE_VOICE_SETTING:
2438 hci_cc_write_voice_setting(hdev, skb);
2439 break;
2440
2441 case HCI_OP_HOST_BUFFER_SIZE:
2442 hci_cc_host_buffer_size(hdev, skb);
2443 break;
2444
Marcel Holtmann333140b2008-07-14 20:13:48 +02002445 case HCI_OP_WRITE_SSP_MODE:
2446 hci_cc_write_ssp_mode(hdev, skb);
2447 break;
2448
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002449 case HCI_OP_READ_LOCAL_VERSION:
2450 hci_cc_read_local_version(hdev, skb);
2451 break;
2452
2453 case HCI_OP_READ_LOCAL_COMMANDS:
2454 hci_cc_read_local_commands(hdev, skb);
2455 break;
2456
2457 case HCI_OP_READ_LOCAL_FEATURES:
2458 hci_cc_read_local_features(hdev, skb);
2459 break;
2460
Andre Guedes971e3a42011-06-30 19:20:52 -03002461 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2462 hci_cc_read_local_ext_features(hdev, skb);
2463 break;
2464
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002465 case HCI_OP_READ_BUFFER_SIZE:
2466 hci_cc_read_buffer_size(hdev, skb);
2467 break;
2468
2469 case HCI_OP_READ_BD_ADDR:
2470 hci_cc_read_bd_addr(hdev, skb);
2471 break;
2472
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002473 case HCI_OP_READ_DATA_BLOCK_SIZE:
2474 hci_cc_read_data_block_size(hdev, skb);
2475 break;
2476
Johan Hedberg23bb5762010-12-21 23:01:27 +02002477 case HCI_OP_WRITE_CA_TIMEOUT:
2478 hci_cc_write_ca_timeout(hdev, skb);
2479 break;
2480
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002481 case HCI_OP_READ_FLOW_CONTROL_MODE:
2482 hci_cc_read_flow_control_mode(hdev, skb);
2483 break;
2484
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002485 case HCI_OP_READ_LOCAL_AMP_INFO:
2486 hci_cc_read_local_amp_info(hdev, skb);
2487 break;
2488
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002489 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2490 hci_cc_read_local_amp_assoc(hdev, skb);
2491 break;
2492
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002493 case HCI_OP_DELETE_STORED_LINK_KEY:
2494 hci_cc_delete_stored_link_key(hdev, skb);
2495 break;
2496
Johan Hedbergd5859e22011-01-25 01:19:58 +02002497 case HCI_OP_SET_EVENT_MASK:
2498 hci_cc_set_event_mask(hdev, skb);
2499 break;
2500
2501 case HCI_OP_WRITE_INQUIRY_MODE:
2502 hci_cc_write_inquiry_mode(hdev, skb);
2503 break;
2504
2505 case HCI_OP_READ_INQ_RSP_TX_POWER:
2506 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2507 break;
2508
2509 case HCI_OP_SET_EVENT_FLT:
2510 hci_cc_set_event_flt(hdev, skb);
2511 break;
2512
Johan Hedberg980e1a52011-01-22 06:10:07 +02002513 case HCI_OP_PIN_CODE_REPLY:
2514 hci_cc_pin_code_reply(hdev, skb);
2515 break;
2516
2517 case HCI_OP_PIN_CODE_NEG_REPLY:
2518 hci_cc_pin_code_neg_reply(hdev, skb);
2519 break;
2520
Szymon Jancc35938b2011-03-22 13:12:21 +01002521 case HCI_OP_READ_LOCAL_OOB_DATA:
2522 hci_cc_read_local_oob_data_reply(hdev, skb);
2523 break;
2524
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002525 case HCI_OP_LE_READ_BUFFER_SIZE:
2526 hci_cc_le_read_buffer_size(hdev, skb);
2527 break;
2528
Johan Hedberg8fa19092012-10-19 20:57:49 +03002529 case HCI_OP_LE_READ_ADV_TX_POWER:
2530 hci_cc_le_read_adv_tx_power(hdev, skb);
2531 break;
2532
Johan Hedberge36b04c2012-10-19 20:57:47 +03002533 case HCI_OP_LE_SET_EVENT_MASK:
2534 hci_cc_le_set_event_mask(hdev, skb);
2535 break;
2536
Johan Hedberga5c29682011-02-19 12:05:57 -03002537 case HCI_OP_USER_CONFIRM_REPLY:
2538 hci_cc_user_confirm_reply(hdev, skb);
2539 break;
2540
2541 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2542 hci_cc_user_confirm_neg_reply(hdev, skb);
2543 break;
2544
Brian Gix1143d452011-11-23 08:28:34 -08002545 case HCI_OP_USER_PASSKEY_REPLY:
2546 hci_cc_user_passkey_reply(hdev, skb);
2547 break;
2548
2549 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2550 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002551 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002552
2553 case HCI_OP_LE_SET_SCAN_PARAM:
2554 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002555 break;
2556
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002557 case HCI_OP_LE_SET_SCAN_ENABLE:
2558 hci_cc_le_set_scan_enable(hdev, skb);
2559 break;
2560
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002561 case HCI_OP_LE_LTK_REPLY:
2562 hci_cc_le_ltk_reply(hdev, skb);
2563 break;
2564
2565 case HCI_OP_LE_LTK_NEG_REPLY:
2566 hci_cc_le_ltk_neg_reply(hdev, skb);
2567 break;
2568
Andre Guedesf9b49302011-06-30 19:20:53 -03002569 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2570 hci_cc_write_le_host_supported(hdev, skb);
2571 break;
2572
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002573 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2574 hci_cc_write_remote_amp_assoc(hdev, skb);
2575 break;
2576
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002577 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002578 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002579 break;
2580 }
2581
Ville Tervo6bd32322011-02-16 16:32:41 +02002582 if (ev->opcode != HCI_OP_NOP)
2583 del_timer(&hdev->cmd_timer);
2584
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002585 if (ev->ncmd) {
2586 atomic_set(&hdev->cmd_cnt, 1);
2587 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002588 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002589 }
2590}
2591
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002592static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002593{
2594 struct hci_ev_cmd_status *ev = (void *) skb->data;
2595 __u16 opcode;
2596
2597 skb_pull(skb, sizeof(*ev));
2598
2599 opcode = __le16_to_cpu(ev->opcode);
2600
2601 switch (opcode) {
2602 case HCI_OP_INQUIRY:
2603 hci_cs_inquiry(hdev, ev->status);
2604 break;
2605
2606 case HCI_OP_CREATE_CONN:
2607 hci_cs_create_conn(hdev, ev->status);
2608 break;
2609
2610 case HCI_OP_ADD_SCO:
2611 hci_cs_add_sco(hdev, ev->status);
2612 break;
2613
Marcel Holtmannf8558552008-07-14 20:13:49 +02002614 case HCI_OP_AUTH_REQUESTED:
2615 hci_cs_auth_requested(hdev, ev->status);
2616 break;
2617
2618 case HCI_OP_SET_CONN_ENCRYPT:
2619 hci_cs_set_conn_encrypt(hdev, ev->status);
2620 break;
2621
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002622 case HCI_OP_REMOTE_NAME_REQ:
2623 hci_cs_remote_name_req(hdev, ev->status);
2624 break;
2625
Marcel Holtmann769be972008-07-14 20:13:49 +02002626 case HCI_OP_READ_REMOTE_FEATURES:
2627 hci_cs_read_remote_features(hdev, ev->status);
2628 break;
2629
2630 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2631 hci_cs_read_remote_ext_features(hdev, ev->status);
2632 break;
2633
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002634 case HCI_OP_SETUP_SYNC_CONN:
2635 hci_cs_setup_sync_conn(hdev, ev->status);
2636 break;
2637
2638 case HCI_OP_SNIFF_MODE:
2639 hci_cs_sniff_mode(hdev, ev->status);
2640 break;
2641
2642 case HCI_OP_EXIT_SNIFF_MODE:
2643 hci_cs_exit_sniff_mode(hdev, ev->status);
2644 break;
2645
Johan Hedberg8962ee72011-01-20 12:40:27 +02002646 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002647 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002648 break;
2649
Ville Tervofcd89c02011-02-10 22:38:47 -03002650 case HCI_OP_LE_CREATE_CONN:
2651 hci_cs_le_create_conn(hdev, ev->status);
2652 break;
2653
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002654 case HCI_OP_LE_START_ENC:
2655 hci_cs_le_start_enc(hdev, ev->status);
2656 break;
2657
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002658 case HCI_OP_CREATE_PHY_LINK:
2659 hci_cs_create_phylink(hdev, ev->status);
2660 break;
2661
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002662 case HCI_OP_ACCEPT_PHY_LINK:
2663 hci_cs_accept_phylink(hdev, ev->status);
2664 break;
2665
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002666 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002667 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002668 break;
2669 }
2670
Ville Tervo6bd32322011-02-16 16:32:41 +02002671 if (ev->opcode != HCI_OP_NOP)
2672 del_timer(&hdev->cmd_timer);
2673
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002674 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002675 atomic_set(&hdev->cmd_cnt, 1);
2676 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002677 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002678 }
2679}
2680
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002681static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002682{
2683 struct hci_ev_role_change *ev = (void *) skb->data;
2684 struct hci_conn *conn;
2685
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002686 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002687
2688 hci_dev_lock(hdev);
2689
2690 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2691 if (conn) {
2692 if (!ev->status) {
2693 if (ev->role)
2694 conn->link_mode &= ~HCI_LM_MASTER;
2695 else
2696 conn->link_mode |= HCI_LM_MASTER;
2697 }
2698
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002699 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002700
2701 hci_role_switch_cfm(conn, ev->status, ev->role);
2702 }
2703
2704 hci_dev_unlock(hdev);
2705}
2706
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002707static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002708{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002709 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710 int i;
2711
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002712 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2713 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2714 return;
2715 }
2716
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002717 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002718 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719 BT_DBG("%s bad parameters", hdev->name);
2720 return;
2721 }
2722
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002723 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2724
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002725 for (i = 0; i < ev->num_hndl; i++) {
2726 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002727 struct hci_conn *conn;
2728 __u16 handle, count;
2729
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002730 handle = __le16_to_cpu(info->handle);
2731 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002732
2733 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002734 if (!conn)
2735 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002736
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002737 conn->sent -= count;
2738
2739 switch (conn->type) {
2740 case ACL_LINK:
2741 hdev->acl_cnt += count;
2742 if (hdev->acl_cnt > hdev->acl_pkts)
2743 hdev->acl_cnt = hdev->acl_pkts;
2744 break;
2745
2746 case LE_LINK:
2747 if (hdev->le_pkts) {
2748 hdev->le_cnt += count;
2749 if (hdev->le_cnt > hdev->le_pkts)
2750 hdev->le_cnt = hdev->le_pkts;
2751 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002752 hdev->acl_cnt += count;
2753 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002754 hdev->acl_cnt = hdev->acl_pkts;
2755 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002756 break;
2757
2758 case SCO_LINK:
2759 hdev->sco_cnt += count;
2760 if (hdev->sco_cnt > hdev->sco_pkts)
2761 hdev->sco_cnt = hdev->sco_pkts;
2762 break;
2763
2764 default:
2765 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2766 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002767 }
2768 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002769
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002770 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002771}
2772
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002773static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2774 __u16 handle)
2775{
2776 struct hci_chan *chan;
2777
2778 switch (hdev->dev_type) {
2779 case HCI_BREDR:
2780 return hci_conn_hash_lookup_handle(hdev, handle);
2781 case HCI_AMP:
2782 chan = hci_chan_lookup_handle(hdev, handle);
2783 if (chan)
2784 return chan->conn;
2785 break;
2786 default:
2787 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2788 break;
2789 }
2790
2791 return NULL;
2792}
2793
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002794static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002795{
2796 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2797 int i;
2798
2799 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2800 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2801 return;
2802 }
2803
2804 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002805 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002806 BT_DBG("%s bad parameters", hdev->name);
2807 return;
2808 }
2809
2810 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002811 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002812
2813 for (i = 0; i < ev->num_hndl; i++) {
2814 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002815 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002816 __u16 handle, block_count;
2817
2818 handle = __le16_to_cpu(info->handle);
2819 block_count = __le16_to_cpu(info->blocks);
2820
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002821 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002822 if (!conn)
2823 continue;
2824
2825 conn->sent -= block_count;
2826
2827 switch (conn->type) {
2828 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002829 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002830 hdev->block_cnt += block_count;
2831 if (hdev->block_cnt > hdev->num_blocks)
2832 hdev->block_cnt = hdev->num_blocks;
2833 break;
2834
2835 default:
2836 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2837 break;
2838 }
2839 }
2840
2841 queue_work(hdev->workqueue, &hdev->tx_work);
2842}
2843
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002844static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002845{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002846 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002847 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002848
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002849 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850
2851 hci_dev_lock(hdev);
2852
Marcel Holtmann04837f62006-07-03 10:02:33 +02002853 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2854 if (conn) {
2855 conn->mode = ev->mode;
2856 conn->interval = __le16_to_cpu(ev->interval);
2857
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002858 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2859 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002860 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002861 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002862 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002863 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002864 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002865
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002866 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002867 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002868 }
2869
2870 hci_dev_unlock(hdev);
2871}
2872
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002873static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002875 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2876 struct hci_conn *conn;
2877
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002878 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002879
2880 hci_dev_lock(hdev);
2881
2882 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002883 if (!conn)
2884 goto unlock;
2885
2886 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002887 hci_conn_hold(conn);
2888 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2889 hci_conn_put(conn);
2890 }
2891
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002892 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002893 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002894 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002895 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002896 u8 secure;
2897
2898 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2899 secure = 1;
2900 else
2901 secure = 0;
2902
Johan Hedberg744cf192011-11-08 20:40:14 +02002903 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002904 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002905
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002906unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002907 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908}
2909
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002910static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002912 struct hci_ev_link_key_req *ev = (void *) skb->data;
2913 struct hci_cp_link_key_reply cp;
2914 struct hci_conn *conn;
2915 struct link_key *key;
2916
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002917 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002918
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002919 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002920 return;
2921
2922 hci_dev_lock(hdev);
2923
2924 key = hci_find_link_key(hdev, &ev->bdaddr);
2925 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002926 BT_DBG("%s link key not found for %pMR", hdev->name,
2927 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002928 goto not_found;
2929 }
2930
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002931 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2932 &ev->bdaddr);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002933
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002934 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002935 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002936 BT_DBG("%s ignoring debug key", hdev->name);
2937 goto not_found;
2938 }
2939
2940 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002941 if (conn) {
2942 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002943 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002944 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2945 goto not_found;
2946 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002947
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002948 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002949 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002950 BT_DBG("%s ignoring key unauthenticated for high security",
2951 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002952 goto not_found;
2953 }
2954
2955 conn->key_type = key->type;
2956 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002957 }
2958
2959 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002960 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002961
2962 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2963
2964 hci_dev_unlock(hdev);
2965
2966 return;
2967
2968not_found:
2969 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2970 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002971}
2972
Gustavo Padovan6039aa732012-05-23 04:04:18 -03002973static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002975 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2976 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002977 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002978
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002979 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002980
2981 hci_dev_lock(hdev);
2982
2983 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2984 if (conn) {
2985 hci_conn_hold(conn);
2986 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002987 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002988
2989 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2990 conn->key_type = ev->key_type;
2991
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002992 hci_conn_put(conn);
2993 }
2994
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002995 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002996 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002997 ev->key_type, pin_len);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002998
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002999 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000}
3001
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003002static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02003003{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003004 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02003005 struct hci_conn *conn;
3006
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003007 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02003008
3009 hci_dev_lock(hdev);
3010
3011 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003012 if (conn && !ev->status) {
3013 struct inquiry_entry *ie;
3014
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003015 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3016 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003017 ie->data.clock_offset = ev->clock_offset;
3018 ie->timestamp = jiffies;
3019 }
3020 }
3021
3022 hci_dev_unlock(hdev);
3023}
3024
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003025static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02003026{
3027 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
3028 struct hci_conn *conn;
3029
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003030 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02003031
3032 hci_dev_lock(hdev);
3033
3034 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3035 if (conn && !ev->status)
3036 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
3037
3038 hci_dev_unlock(hdev);
3039}
3040
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003041static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003042{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003043 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003044 struct inquiry_entry *ie;
3045
3046 BT_DBG("%s", hdev->name);
3047
3048 hci_dev_lock(hdev);
3049
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003050 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3051 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003052 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
3053 ie->timestamp = jiffies;
3054 }
3055
3056 hci_dev_unlock(hdev);
3057}
3058
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003059static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
3060 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003061{
3062 struct inquiry_data data;
3063 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003064 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003065
3066 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3067
3068 if (!num_rsp)
3069 return;
3070
Andre Guedes1519cc12012-03-21 00:03:38 -03003071 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3072 return;
3073
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003074 hci_dev_lock(hdev);
3075
3076 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01003077 struct inquiry_info_with_rssi_and_pscan_mode *info;
3078 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003079
Johan Hedberge17acd42011-03-30 23:57:16 +03003080 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003081 bacpy(&data.bdaddr, &info->bdaddr);
3082 data.pscan_rep_mode = info->pscan_rep_mode;
3083 data.pscan_period_mode = info->pscan_period_mode;
3084 data.pscan_mode = info->pscan_mode;
3085 memcpy(data.dev_class, info->dev_class, 3);
3086 data.clock_offset = info->clock_offset;
3087 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003088 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003089
3090 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003091 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003092 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003093 info->dev_class, info->rssi,
3094 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003095 }
3096 } else {
3097 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
3098
Johan Hedberge17acd42011-03-30 23:57:16 +03003099 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003100 bacpy(&data.bdaddr, &info->bdaddr);
3101 data.pscan_rep_mode = info->pscan_rep_mode;
3102 data.pscan_period_mode = info->pscan_period_mode;
3103 data.pscan_mode = 0x00;
3104 memcpy(data.dev_class, info->dev_class, 3);
3105 data.clock_offset = info->clock_offset;
3106 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003107 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02003108 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003109 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02003110 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003111 info->dev_class, info->rssi,
3112 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003113 }
3114 }
3115
3116 hci_dev_unlock(hdev);
3117}
3118
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003119static void hci_remote_ext_features_evt(struct hci_dev *hdev,
3120 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003121{
Marcel Holtmann41a96212008-07-14 20:13:48 +02003122 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
3123 struct hci_conn *conn;
3124
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003125 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003126
Marcel Holtmann41a96212008-07-14 20:13:48 +02003127 hci_dev_lock(hdev);
3128
3129 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02003130 if (!conn)
3131 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003132
Johan Hedbergccd556f2010-11-10 17:11:51 +02003133 if (!ev->status && ev->page == 0x01) {
3134 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003135
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003136 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
3137 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003138 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02003139
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003140 if (ev->features[0] & LMP_HOST_SSP)
Johan Hedberg58a681e2012-01-16 06:47:28 +02003141 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003142 }
3143
Johan Hedbergccd556f2010-11-10 17:11:51 +02003144 if (conn->state != BT_CONFIG)
3145 goto unlock;
3146
Johan Hedberg671267b2012-05-12 16:11:50 -03003147 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02003148 struct hci_cp_remote_name_req cp;
3149 memset(&cp, 0, sizeof(cp));
3150 bacpy(&cp.bdaddr, &conn->dst);
3151 cp.pscan_rep_mode = 0x02;
3152 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02003153 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3154 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003155 conn->dst_type, 0, NULL, 0,
3156 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02003157
Johan Hedberg127178d2010-11-18 22:22:29 +02003158 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02003159 conn->state = BT_CONNECTED;
3160 hci_proto_connect_cfm(conn, ev->status);
3161 hci_conn_put(conn);
3162 }
3163
3164unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02003165 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003166}
3167
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003168static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
3169 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003170{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003171 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
3172 struct hci_conn *conn;
3173
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003174 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003175
3176 hci_dev_lock(hdev);
3177
3178 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02003179 if (!conn) {
3180 if (ev->link_type == ESCO_LINK)
3181 goto unlock;
3182
3183 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
3184 if (!conn)
3185 goto unlock;
3186
3187 conn->type = SCO_LINK;
3188 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003189
Marcel Holtmann732547f2009-04-19 19:14:14 +02003190 switch (ev->status) {
3191 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003192 conn->handle = __le16_to_cpu(ev->handle);
3193 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02003194
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07003195 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02003196 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02003197 break;
3198
Stephen Coe705e5712010-02-16 11:29:44 -05003199 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003200 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08003201 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02003202 case 0x1f: /* Unspecified error */
3203 if (conn->out && conn->attempt < 2) {
3204 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
3205 (hdev->esco_type & EDR_ESCO_MASK);
3206 hci_setup_sync(conn, conn->link->handle);
3207 goto unlock;
3208 }
3209 /* fall through */
3210
3211 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003212 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02003213 break;
3214 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02003215
3216 hci_proto_connect_cfm(conn, ev->status);
3217 if (ev->status)
3218 hci_conn_del(conn);
3219
3220unlock:
3221 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003222}
3223
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003224static void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003225{
3226 BT_DBG("%s", hdev->name);
3227}
3228
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003229static void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02003230{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003231 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02003232
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003233 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02003234}
3235
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003236static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
3237 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003238{
3239 struct inquiry_data data;
3240 struct extended_inquiry_info *info = (void *) (skb->data + 1);
3241 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303242 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003243
3244 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
3245
3246 if (!num_rsp)
3247 return;
3248
Andre Guedes1519cc12012-03-21 00:03:38 -03003249 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3250 return;
3251
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003252 hci_dev_lock(hdev);
3253
Johan Hedberge17acd42011-03-30 23:57:16 +03003254 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003255 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003256
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003257 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003258 data.pscan_rep_mode = info->pscan_rep_mode;
3259 data.pscan_period_mode = info->pscan_period_mode;
3260 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003261 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003262 data.clock_offset = info->clock_offset;
3263 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003264 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003265
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003266 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003267 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003268 sizeof(info->data),
3269 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003270 else
3271 name_known = true;
3272
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003273 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003274 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303275 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003276 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003277 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303278 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003279 }
3280
3281 hci_dev_unlock(hdev);
3282}
3283
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003284static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3285 struct sk_buff *skb)
3286{
3287 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3288 struct hci_conn *conn;
3289
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003290 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003291 __le16_to_cpu(ev->handle));
3292
3293 hci_dev_lock(hdev);
3294
3295 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3296 if (!conn)
3297 goto unlock;
3298
3299 if (!ev->status)
3300 conn->sec_level = conn->pending_sec_level;
3301
3302 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3303
3304 if (ev->status && conn->state == BT_CONNECTED) {
3305 hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE);
3306 hci_conn_put(conn);
3307 goto unlock;
3308 }
3309
3310 if (conn->state == BT_CONFIG) {
3311 if (!ev->status)
3312 conn->state = BT_CONNECTED;
3313
3314 hci_proto_connect_cfm(conn, ev->status);
3315 hci_conn_put(conn);
3316 } else {
3317 hci_auth_cfm(conn, ev->status);
3318
3319 hci_conn_hold(conn);
3320 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
3321 hci_conn_put(conn);
3322 }
3323
3324unlock:
3325 hci_dev_unlock(hdev);
3326}
3327
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003328static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003329{
3330 /* If remote requests dedicated bonding follow that lead */
3331 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3332 /* If both remote and local IO capabilities allow MITM
3333 * protection then require it, otherwise don't */
3334 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3335 return 0x02;
3336 else
3337 return 0x03;
3338 }
3339
3340 /* If remote requests no-bonding follow that lead */
3341 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003342 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003343
3344 return conn->auth_type;
3345}
3346
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003347static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003348{
3349 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3350 struct hci_conn *conn;
3351
3352 BT_DBG("%s", hdev->name);
3353
3354 hci_dev_lock(hdev);
3355
3356 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003357 if (!conn)
3358 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003359
Johan Hedberg03b555e2011-01-04 15:40:05 +02003360 hci_conn_hold(conn);
3361
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003362 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003363 goto unlock;
3364
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003365 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003366 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003367 struct hci_cp_io_capability_reply cp;
3368
3369 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303370 /* Change the IO capability from KeyboardDisplay
3371 * to DisplayYesNo as it is not supported by BT spec. */
3372 cp.capability = (conn->io_capability == 0x04) ?
3373 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003374 conn->auth_type = hci_get_auth_req(conn);
3375 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003376
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003377 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3378 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003379 cp.oob_data = 0x01;
3380 else
3381 cp.oob_data = 0x00;
3382
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003383 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003384 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003385 } else {
3386 struct hci_cp_io_capability_neg_reply cp;
3387
3388 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003389 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003390
3391 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003392 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003393 }
3394
3395unlock:
3396 hci_dev_unlock(hdev);
3397}
3398
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003399static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003400{
3401 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3402 struct hci_conn *conn;
3403
3404 BT_DBG("%s", hdev->name);
3405
3406 hci_dev_lock(hdev);
3407
3408 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3409 if (!conn)
3410 goto unlock;
3411
Johan Hedberg03b555e2011-01-04 15:40:05 +02003412 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003413 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003414 if (ev->oob_data)
3415 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003416
3417unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003418 hci_dev_unlock(hdev);
3419}
3420
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003421static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3422 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003423{
3424 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003425 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003426 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003427
3428 BT_DBG("%s", hdev->name);
3429
3430 hci_dev_lock(hdev);
3431
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003432 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003433 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003434
Johan Hedberg7a828902011-04-28 11:28:53 -07003435 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3436 if (!conn)
3437 goto unlock;
3438
3439 loc_mitm = (conn->auth_type & 0x01);
3440 rem_mitm = (conn->remote_auth & 0x01);
3441
3442 /* If we require MITM but the remote device can't provide that
3443 * (it has NoInputNoOutput) then reject the confirmation
3444 * request. The only exception is when we're dedicated bonding
3445 * initiators (connect_cfm_cb set) since then we always have the MITM
3446 * bit set. */
3447 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3448 BT_DBG("Rejecting request: remote device can't provide MITM");
3449 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003450 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003451 goto unlock;
3452 }
3453
3454 /* If no side requires MITM protection; auto-accept */
3455 if ((!loc_mitm || conn->remote_cap == 0x03) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03003456 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003457
3458 /* If we're not the initiators request authorization to
3459 * proceed from user space (mgmt_user_confirm with
3460 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003461 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003462 BT_DBG("Confirming auto-accept as acceptor");
3463 confirm_hint = 1;
3464 goto confirm;
3465 }
3466
Johan Hedberg9f616562011-04-28 11:28:54 -07003467 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003468 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003469
3470 if (hdev->auto_accept_delay > 0) {
3471 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3472 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3473 goto unlock;
3474 }
3475
Johan Hedberg7a828902011-04-28 11:28:53 -07003476 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003477 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003478 goto unlock;
3479 }
3480
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003481confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003482 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003483 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003484
3485unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003486 hci_dev_unlock(hdev);
3487}
3488
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003489static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3490 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003491{
3492 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3493
3494 BT_DBG("%s", hdev->name);
3495
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003496 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003497 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003498}
3499
Johan Hedberg92a25252012-09-06 18:39:26 +03003500static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3501 struct sk_buff *skb)
3502{
3503 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3504 struct hci_conn *conn;
3505
3506 BT_DBG("%s", hdev->name);
3507
3508 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3509 if (!conn)
3510 return;
3511
3512 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3513 conn->passkey_entered = 0;
3514
3515 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3516 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3517 conn->dst_type, conn->passkey_notify,
3518 conn->passkey_entered);
3519}
3520
3521static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3522{
3523 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3524 struct hci_conn *conn;
3525
3526 BT_DBG("%s", hdev->name);
3527
3528 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3529 if (!conn)
3530 return;
3531
3532 switch (ev->type) {
3533 case HCI_KEYPRESS_STARTED:
3534 conn->passkey_entered = 0;
3535 return;
3536
3537 case HCI_KEYPRESS_ENTERED:
3538 conn->passkey_entered++;
3539 break;
3540
3541 case HCI_KEYPRESS_ERASED:
3542 conn->passkey_entered--;
3543 break;
3544
3545 case HCI_KEYPRESS_CLEARED:
3546 conn->passkey_entered = 0;
3547 break;
3548
3549 case HCI_KEYPRESS_COMPLETED:
3550 return;
3551 }
3552
3553 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3554 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3555 conn->dst_type, conn->passkey_notify,
3556 conn->passkey_entered);
3557}
3558
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003559static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3560 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003561{
3562 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3563 struct hci_conn *conn;
3564
3565 BT_DBG("%s", hdev->name);
3566
3567 hci_dev_lock(hdev);
3568
3569 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003570 if (!conn)
3571 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003572
Johan Hedberg2a611692011-02-19 12:06:00 -03003573 /* To avoid duplicate auth_failed events to user space we check
3574 * the HCI_CONN_AUTH_PEND flag which will be set if we
3575 * initiated the authentication. A traditional auth_complete
3576 * event gets always produced as initiator and is also mapped to
3577 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003578 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003579 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003580 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003581
3582 hci_conn_put(conn);
3583
3584unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003585 hci_dev_unlock(hdev);
3586}
3587
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003588static void hci_remote_host_features_evt(struct hci_dev *hdev,
3589 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003590{
3591 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3592 struct inquiry_entry *ie;
3593
3594 BT_DBG("%s", hdev->name);
3595
3596 hci_dev_lock(hdev);
3597
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003598 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3599 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003600 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003601
3602 hci_dev_unlock(hdev);
3603}
3604
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003605static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3606 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003607{
3608 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3609 struct oob_data *data;
3610
3611 BT_DBG("%s", hdev->name);
3612
3613 hci_dev_lock(hdev);
3614
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003615 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003616 goto unlock;
3617
Szymon Janc2763eda2011-03-22 13:12:22 +01003618 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3619 if (data) {
3620 struct hci_cp_remote_oob_data_reply cp;
3621
3622 bacpy(&cp.bdaddr, &ev->bdaddr);
3623 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3624 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3625
3626 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003627 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003628 } else {
3629 struct hci_cp_remote_oob_data_neg_reply cp;
3630
3631 bacpy(&cp.bdaddr, &ev->bdaddr);
3632 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003633 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003634 }
3635
Szymon Jance1ba1f12011-04-06 13:01:59 +02003636unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003637 hci_dev_unlock(hdev);
3638}
3639
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003640static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003641{
3642 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3643 struct hci_conn *conn;
3644
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003645 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003646
3647 hci_dev_lock(hdev);
3648
Andre Guedesb47a09b2012-07-27 15:10:15 -03003649 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003650 if (!conn) {
3651 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3652 if (!conn) {
3653 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003654 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003655 }
Andre Guedes29b79882011-05-31 14:20:54 -03003656
3657 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003658
3659 if (ev->role == LE_CONN_ROLE_MASTER) {
3660 conn->out = true;
3661 conn->link_mode |= HCI_LM_MASTER;
3662 }
Ville Tervob62f3282011-02-10 22:38:50 -03003663 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003664
Andre Guedescd17dec2012-07-27 15:10:16 -03003665 if (ev->status) {
3666 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3667 conn->dst_type, ev->status);
3668 hci_proto_connect_cfm(conn, ev->status);
3669 conn->state = BT_CLOSED;
3670 hci_conn_del(conn);
3671 goto unlock;
3672 }
3673
Johan Hedbergb644ba32012-01-17 21:48:47 +02003674 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3675 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003676 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003677
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003678 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003679 conn->handle = __le16_to_cpu(ev->handle);
3680 conn->state = BT_CONNECTED;
3681
3682 hci_conn_hold_device(conn);
3683 hci_conn_add_sysfs(conn);
3684
3685 hci_proto_connect_cfm(conn, ev->status);
3686
3687unlock:
3688 hci_dev_unlock(hdev);
3689}
3690
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003691static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003692{
Andre Guedese95beb42011-09-26 20:48:35 -03003693 u8 num_reports = skb->data[0];
3694 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003695 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003696
3697 hci_dev_lock(hdev);
3698
Andre Guedese95beb42011-09-26 20:48:35 -03003699 while (num_reports--) {
3700 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003701
Andre Guedes3c9e9192012-01-10 18:20:50 -03003702 rssi = ev->data[ev->length];
3703 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003704 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003705
Andre Guedese95beb42011-09-26 20:48:35 -03003706 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003707 }
3708
3709 hci_dev_unlock(hdev);
3710}
3711
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003712static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003713{
3714 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3715 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003716 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003717 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003718 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003719
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003720 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003721
3722 hci_dev_lock(hdev);
3723
3724 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003725 if (conn == NULL)
3726 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003727
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003728 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3729 if (ltk == NULL)
3730 goto not_found;
3731
3732 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003733 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003734
3735 if (ltk->authenticated)
3736 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003737
3738 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3739
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003740 if (ltk->type & HCI_SMP_STK) {
3741 list_del(&ltk->list);
3742 kfree(ltk);
3743 }
3744
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003745 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003746
3747 return;
3748
3749not_found:
3750 neg.handle = ev->handle;
3751 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3752 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003753}
3754
Gustavo Padovan6039aa732012-05-23 04:04:18 -03003755static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003756{
3757 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3758
3759 skb_pull(skb, sizeof(*le_ev));
3760
3761 switch (le_ev->subevent) {
3762 case HCI_EV_LE_CONN_COMPLETE:
3763 hci_le_conn_complete_evt(hdev, skb);
3764 break;
3765
Andre Guedes9aa04c92011-05-26 16:23:51 -03003766 case HCI_EV_LE_ADVERTISING_REPORT:
3767 hci_le_adv_report_evt(hdev, skb);
3768 break;
3769
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003770 case HCI_EV_LE_LTK_REQ:
3771 hci_le_ltk_request_evt(hdev, skb);
3772 break;
3773
Ville Tervofcd89c02011-02-10 22:38:47 -03003774 default:
3775 break;
3776 }
3777}
3778
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003779static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3780{
3781 struct hci_ev_channel_selected *ev = (void *) skb->data;
3782 struct hci_conn *hcon;
3783
3784 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3785
3786 skb_pull(skb, sizeof(*ev));
3787
3788 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3789 if (!hcon)
3790 return;
3791
3792 amp_read_loc_assoc_final_data(hdev, hcon);
3793}
3794
Linus Torvalds1da177e2005-04-16 15:20:36 -07003795void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3796{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003797 struct hci_event_hdr *hdr = (void *) skb->data;
3798 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003799
3800 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3801
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003802 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003803 case HCI_EV_INQUIRY_COMPLETE:
3804 hci_inquiry_complete_evt(hdev, skb);
3805 break;
3806
3807 case HCI_EV_INQUIRY_RESULT:
3808 hci_inquiry_result_evt(hdev, skb);
3809 break;
3810
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003811 case HCI_EV_CONN_COMPLETE:
3812 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003813 break;
3814
Linus Torvalds1da177e2005-04-16 15:20:36 -07003815 case HCI_EV_CONN_REQUEST:
3816 hci_conn_request_evt(hdev, skb);
3817 break;
3818
Linus Torvalds1da177e2005-04-16 15:20:36 -07003819 case HCI_EV_DISCONN_COMPLETE:
3820 hci_disconn_complete_evt(hdev, skb);
3821 break;
3822
Linus Torvalds1da177e2005-04-16 15:20:36 -07003823 case HCI_EV_AUTH_COMPLETE:
3824 hci_auth_complete_evt(hdev, skb);
3825 break;
3826
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003827 case HCI_EV_REMOTE_NAME:
3828 hci_remote_name_evt(hdev, skb);
3829 break;
3830
Linus Torvalds1da177e2005-04-16 15:20:36 -07003831 case HCI_EV_ENCRYPT_CHANGE:
3832 hci_encrypt_change_evt(hdev, skb);
3833 break;
3834
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003835 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3836 hci_change_link_key_complete_evt(hdev, skb);
3837 break;
3838
3839 case HCI_EV_REMOTE_FEATURES:
3840 hci_remote_features_evt(hdev, skb);
3841 break;
3842
3843 case HCI_EV_REMOTE_VERSION:
3844 hci_remote_version_evt(hdev, skb);
3845 break;
3846
3847 case HCI_EV_QOS_SETUP_COMPLETE:
3848 hci_qos_setup_complete_evt(hdev, skb);
3849 break;
3850
3851 case HCI_EV_CMD_COMPLETE:
3852 hci_cmd_complete_evt(hdev, skb);
3853 break;
3854
3855 case HCI_EV_CMD_STATUS:
3856 hci_cmd_status_evt(hdev, skb);
3857 break;
3858
3859 case HCI_EV_ROLE_CHANGE:
3860 hci_role_change_evt(hdev, skb);
3861 break;
3862
3863 case HCI_EV_NUM_COMP_PKTS:
3864 hci_num_comp_pkts_evt(hdev, skb);
3865 break;
3866
3867 case HCI_EV_MODE_CHANGE:
3868 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003869 break;
3870
3871 case HCI_EV_PIN_CODE_REQ:
3872 hci_pin_code_request_evt(hdev, skb);
3873 break;
3874
3875 case HCI_EV_LINK_KEY_REQ:
3876 hci_link_key_request_evt(hdev, skb);
3877 break;
3878
3879 case HCI_EV_LINK_KEY_NOTIFY:
3880 hci_link_key_notify_evt(hdev, skb);
3881 break;
3882
3883 case HCI_EV_CLOCK_OFFSET:
3884 hci_clock_offset_evt(hdev, skb);
3885 break;
3886
Marcel Holtmanna8746412008-07-14 20:13:46 +02003887 case HCI_EV_PKT_TYPE_CHANGE:
3888 hci_pkt_type_change_evt(hdev, skb);
3889 break;
3890
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003891 case HCI_EV_PSCAN_REP_MODE:
3892 hci_pscan_rep_mode_evt(hdev, skb);
3893 break;
3894
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003895 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3896 hci_inquiry_result_with_rssi_evt(hdev, skb);
3897 break;
3898
3899 case HCI_EV_REMOTE_EXT_FEATURES:
3900 hci_remote_ext_features_evt(hdev, skb);
3901 break;
3902
3903 case HCI_EV_SYNC_CONN_COMPLETE:
3904 hci_sync_conn_complete_evt(hdev, skb);
3905 break;
3906
3907 case HCI_EV_SYNC_CONN_CHANGED:
3908 hci_sync_conn_changed_evt(hdev, skb);
3909 break;
3910
Marcel Holtmann04837f62006-07-03 10:02:33 +02003911 case HCI_EV_SNIFF_SUBRATE:
3912 hci_sniff_subrate_evt(hdev, skb);
3913 break;
3914
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003915 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3916 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917 break;
3918
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003919 case HCI_EV_KEY_REFRESH_COMPLETE:
3920 hci_key_refresh_complete_evt(hdev, skb);
3921 break;
3922
Marcel Holtmann04936842008-07-14 20:13:48 +02003923 case HCI_EV_IO_CAPA_REQUEST:
3924 hci_io_capa_request_evt(hdev, skb);
3925 break;
3926
Johan Hedberg03b555e2011-01-04 15:40:05 +02003927 case HCI_EV_IO_CAPA_REPLY:
3928 hci_io_capa_reply_evt(hdev, skb);
3929 break;
3930
Johan Hedberga5c29682011-02-19 12:05:57 -03003931 case HCI_EV_USER_CONFIRM_REQUEST:
3932 hci_user_confirm_request_evt(hdev, skb);
3933 break;
3934
Brian Gix1143d452011-11-23 08:28:34 -08003935 case HCI_EV_USER_PASSKEY_REQUEST:
3936 hci_user_passkey_request_evt(hdev, skb);
3937 break;
3938
Johan Hedberg92a25252012-09-06 18:39:26 +03003939 case HCI_EV_USER_PASSKEY_NOTIFY:
3940 hci_user_passkey_notify_evt(hdev, skb);
3941 break;
3942
3943 case HCI_EV_KEYPRESS_NOTIFY:
3944 hci_keypress_notify_evt(hdev, skb);
3945 break;
3946
Marcel Holtmann04936842008-07-14 20:13:48 +02003947 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3948 hci_simple_pair_complete_evt(hdev, skb);
3949 break;
3950
Marcel Holtmann41a96212008-07-14 20:13:48 +02003951 case HCI_EV_REMOTE_HOST_FEATURES:
3952 hci_remote_host_features_evt(hdev, skb);
3953 break;
3954
Ville Tervofcd89c02011-02-10 22:38:47 -03003955 case HCI_EV_LE_META:
3956 hci_le_meta_evt(hdev, skb);
3957 break;
3958
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003959 case HCI_EV_CHANNEL_SELECTED:
3960 hci_chan_selected_evt(hdev, skb);
3961 break;
3962
Szymon Janc2763eda2011-03-22 13:12:22 +01003963 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3964 hci_remote_oob_data_request_evt(hdev, skb);
3965 break;
3966
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003967 case HCI_EV_NUM_COMP_BLOCKS:
3968 hci_num_comp_blocks_evt(hdev, skb);
3969 break;
3970
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003971 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003972 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003973 break;
3974 }
3975
3976 kfree_skb(skb);
3977 hdev->stat.evt_rx++;
3978}