blob: 276f3ac06089714060035b7bdab907fa4d86e235 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/fcntl.h>
35#include <linux/init.h>
36#include <linux/skbuff.h>
37#include <linux/interrupt.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <net/sock.h>
39
40#include <asm/system.h>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020041#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <asm/unaligned.h>
43
44#include <net/bluetooth/bluetooth.h>
45#include <net/bluetooth/hci_core.h>
46
Linus Torvalds1da177e2005-04-16 15:20:36 -070047/* Handle HCI Event packets */
48
Marcel Holtmanna9de9242007-10-20 13:33:56 +020049static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070050{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020051 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
Marcel Holtmanna9de9242007-10-20 13:33:56 +020053 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
Andre Guedese6d465c2011-11-09 17:14:26 -030055 if (status) {
56 hci_dev_lock(hdev);
57 mgmt_stop_discovery_failed(hdev, status);
58 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020059 return;
Andre Guedese6d465c2011-11-09 17:14:26 -030060 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
Andre Guedes89352e72011-11-04 14:16:53 -030062 clear_bit(HCI_INQUIRY, &hdev->flags);
63
Johan Hedberg56e5cb82011-11-08 20:40:16 +020064 hci_dev_lock(hdev);
Johan Hedbergff9ef572012-01-04 14:23:45 +020065 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020066 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010067
Johan Hedberg23bb5762010-12-21 23:01:27 +020068 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010069
Marcel Holtmanna9de9242007-10-20 13:33:56 +020070 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070071}
72
Marcel Holtmanna9de9242007-10-20 13:33:56 +020073static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070074{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020075 __u8 status = *((__u8 *) skb->data);
76
77 BT_DBG("%s status 0x%x", hdev->name, status);
78
79 if (status)
80 return;
81
Marcel Holtmanna9de9242007-10-20 13:33:56 +020082 hci_conn_check_pending(hdev);
83}
84
85static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
86{
87 BT_DBG("%s", hdev->name);
88}
89
90static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
91{
92 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
Marcel Holtmanna9de9242007-10-20 13:33:56 +020095 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Marcel Holtmanna9de9242007-10-20 13:33:56 +020097 if (rp->status)
98 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200100 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200102 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
103 if (conn) {
104 if (rp->role)
105 conn->link_mode &= ~HCI_LM_MASTER;
106 else
107 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200109
110 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111}
112
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200113static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
114{
115 struct hci_rp_read_link_policy *rp = (void *) skb->data;
116 struct hci_conn *conn;
117
118 BT_DBG("%s status 0x%x", hdev->name, rp->status);
119
120 if (rp->status)
121 return;
122
123 hci_dev_lock(hdev);
124
125 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
126 if (conn)
127 conn->link_policy = __le16_to_cpu(rp->policy);
128
129 hci_dev_unlock(hdev);
130}
131
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200132static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200134 struct hci_rp_write_link_policy *rp = (void *) skb->data;
135 struct hci_conn *conn;
136 void *sent;
137
138 BT_DBG("%s status 0x%x", hdev->name, rp->status);
139
140 if (rp->status)
141 return;
142
143 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
144 if (!sent)
145 return;
146
147 hci_dev_lock(hdev);
148
149 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200150 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700151 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200152
153 hci_dev_unlock(hdev);
154}
155
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200156static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
157{
158 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
159
160 BT_DBG("%s status 0x%x", hdev->name, rp->status);
161
162 if (rp->status)
163 return;
164
165 hdev->link_policy = __le16_to_cpu(rp->policy);
166}
167
168static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
169{
170 __u8 status = *((__u8 *) skb->data);
171 void *sent;
172
173 BT_DBG("%s status 0x%x", hdev->name, status);
174
175 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
176 if (!sent)
177 return;
178
179 if (!status)
180 hdev->link_policy = get_unaligned_le16(sent);
181
Johan Hedberg23bb5762010-12-21 23:01:27 +0200182 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200183}
184
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200185static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
186{
187 __u8 status = *((__u8 *) skb->data);
188
189 BT_DBG("%s status 0x%x", hdev->name, status);
190
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300191 clear_bit(HCI_RESET, &hdev->flags);
192
Johan Hedberg23bb5762010-12-21 23:01:27 +0200193 hci_req_complete(hdev, HCI_OP_RESET, status);
Andre Guedesd23264a2011-11-25 20:53:38 -0300194
Johan Hedberga297e972012-02-21 17:55:47 +0200195 /* Reset all non-persistent flags */
196 hdev->dev_flags &= ~(BIT(HCI_LE_SCAN));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200197}
198
199static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
200{
201 __u8 status = *((__u8 *) skb->data);
202 void *sent;
203
204 BT_DBG("%s status 0x%x", hdev->name, status);
205
206 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
207 if (!sent)
208 return;
209
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200210 hci_dev_lock(hdev);
211
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200212 if (test_bit(HCI_MGMT, &hdev->dev_flags))
213 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200214 else if (!status)
215 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200216
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200217 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200218}
219
220static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
221{
222 struct hci_rp_read_local_name *rp = (void *) skb->data;
223
224 BT_DBG("%s status 0x%x", hdev->name, rp->status);
225
226 if (rp->status)
227 return;
228
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200229 if (test_bit(HCI_SETUP, &hdev->dev_flags))
230 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200231}
232
233static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
234{
235 __u8 status = *((__u8 *) skb->data);
236 void *sent;
237
238 BT_DBG("%s status 0x%x", hdev->name, status);
239
240 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
241 if (!sent)
242 return;
243
244 if (!status) {
245 __u8 param = *((__u8 *) sent);
246
247 if (param == AUTH_ENABLED)
248 set_bit(HCI_AUTH, &hdev->flags);
249 else
250 clear_bit(HCI_AUTH, &hdev->flags);
251 }
252
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200253 if (test_bit(HCI_MGMT, &hdev->dev_flags))
254 mgmt_auth_enable_complete(hdev, status);
255
Johan Hedberg23bb5762010-12-21 23:01:27 +0200256 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200257}
258
259static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
260{
261 __u8 status = *((__u8 *) skb->data);
262 void *sent;
263
264 BT_DBG("%s status 0x%x", hdev->name, status);
265
266 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
267 if (!sent)
268 return;
269
270 if (!status) {
271 __u8 param = *((__u8 *) sent);
272
273 if (param)
274 set_bit(HCI_ENCRYPT, &hdev->flags);
275 else
276 clear_bit(HCI_ENCRYPT, &hdev->flags);
277 }
278
Johan Hedberg23bb5762010-12-21 23:01:27 +0200279 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200280}
281
282static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
283{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200284 __u8 param, status = *((__u8 *) skb->data);
285 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200286 void *sent;
287
288 BT_DBG("%s status 0x%x", hdev->name, status);
289
290 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
291 if (!sent)
292 return;
293
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200294 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200295
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200296 hci_dev_lock(hdev);
297
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200298 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200299 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200300 hdev->discov_timeout = 0;
301 goto done;
302 }
303
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200304 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
305 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200306
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200307 if (param & SCAN_INQUIRY) {
308 set_bit(HCI_ISCAN, &hdev->flags);
309 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200310 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200311 if (hdev->discov_timeout > 0) {
312 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
313 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
314 to);
315 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200316 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200317 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200318
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200319 if (param & SCAN_PAGE) {
320 set_bit(HCI_PSCAN, &hdev->flags);
321 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200322 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200323 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200324 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200325
326done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200327 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200328 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200329}
330
331static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
332{
333 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
334
335 BT_DBG("%s status 0x%x", hdev->name, rp->status);
336
337 if (rp->status)
338 return;
339
340 memcpy(hdev->dev_class, rp->dev_class, 3);
341
342 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
343 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
344}
345
346static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
347{
348 __u8 status = *((__u8 *) skb->data);
349 void *sent;
350
351 BT_DBG("%s status 0x%x", hdev->name, status);
352
353 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
354 if (!sent)
355 return;
356
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100357 hci_dev_lock(hdev);
358
359 if (status == 0)
360 memcpy(hdev->dev_class, sent, 3);
361
362 if (test_bit(HCI_MGMT, &hdev->dev_flags))
363 mgmt_set_class_of_dev_complete(hdev, sent, status);
364
365 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200366}
367
368static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
369{
370 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200372
373 BT_DBG("%s status 0x%x", hdev->name, rp->status);
374
375 if (rp->status)
376 return;
377
378 setting = __le16_to_cpu(rp->voice_setting);
379
Marcel Holtmannf383f272008-07-14 20:13:47 +0200380 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200381 return;
382
383 hdev->voice_setting = setting;
384
385 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
386
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200387 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200388 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389}
390
391static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
392{
393 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200394 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 void *sent;
396
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200397 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398
Marcel Holtmannf383f272008-07-14 20:13:47 +0200399 if (status)
400 return;
401
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200402 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
403 if (!sent)
404 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405
Marcel Holtmannf383f272008-07-14 20:13:47 +0200406 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
Marcel Holtmannf383f272008-07-14 20:13:47 +0200408 if (hdev->voice_setting == setting)
409 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410
Marcel Holtmannf383f272008-07-14 20:13:47 +0200411 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
Marcel Holtmannf383f272008-07-14 20:13:47 +0200413 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
414
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200415 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200416 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417}
418
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200419static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200421 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200423 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424
Johan Hedberg23bb5762010-12-21 23:01:27 +0200425 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426}
427
Marcel Holtmann333140b2008-07-14 20:13:48 +0200428static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
429{
430 __u8 status = *((__u8 *) skb->data);
431 void *sent;
432
433 BT_DBG("%s status 0x%x", hdev->name, status);
434
Marcel Holtmann333140b2008-07-14 20:13:48 +0200435 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
436 if (!sent)
437 return;
438
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200439 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200440 mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status);
441 else if (!status) {
442 if (*((u8 *) sent))
443 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
444 else
445 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
446 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200447}
448
Johan Hedbergd5859e22011-01-25 01:19:58 +0200449static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
450{
451 if (hdev->features[6] & LMP_EXT_INQ)
452 return 2;
453
454 if (hdev->features[3] & LMP_RSSI_INQ)
455 return 1;
456
457 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
458 hdev->lmp_subver == 0x0757)
459 return 1;
460
461 if (hdev->manufacturer == 15) {
462 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
463 return 1;
464 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
465 return 1;
466 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
467 return 1;
468 }
469
470 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
471 hdev->lmp_subver == 0x1805)
472 return 1;
473
474 return 0;
475}
476
477static void hci_setup_inquiry_mode(struct hci_dev *hdev)
478{
479 u8 mode;
480
481 mode = hci_get_inquiry_mode(hdev);
482
483 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
484}
485
486static void hci_setup_event_mask(struct hci_dev *hdev)
487{
488 /* The second byte is 0xff instead of 0x9f (two reserved bits
489 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
490 * command otherwise */
491 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
492
Ville Tervo6de6c182011-05-27 11:16:21 +0300493 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
494 * any event mask for pre 1.2 devices */
Andrei Emeltchenko5a13b092011-12-01 14:33:28 +0200495 if (hdev->hci_ver < BLUETOOTH_VER_1_2)
Ville Tervo6de6c182011-05-27 11:16:21 +0300496 return;
497
498 events[4] |= 0x01; /* Flow Specification Complete */
499 events[4] |= 0x02; /* Inquiry Result with RSSI */
500 events[4] |= 0x04; /* Read Remote Extended Features Complete */
501 events[5] |= 0x08; /* Synchronous Connection Complete */
502 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200503
504 if (hdev->features[3] & LMP_RSSI_INQ)
505 events[4] |= 0x04; /* Inquiry Result with RSSI */
506
507 if (hdev->features[5] & LMP_SNIFF_SUBR)
508 events[5] |= 0x20; /* Sniff Subrating */
509
510 if (hdev->features[5] & LMP_PAUSE_ENC)
511 events[5] |= 0x80; /* Encryption Key Refresh Complete */
512
513 if (hdev->features[6] & LMP_EXT_INQ)
514 events[5] |= 0x40; /* Extended Inquiry Result */
515
516 if (hdev->features[6] & LMP_NO_FLUSH)
517 events[7] |= 0x01; /* Enhanced Flush Complete */
518
519 if (hdev->features[7] & LMP_LSTO)
520 events[6] |= 0x80; /* Link Supervision Timeout Changed */
521
522 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
523 events[6] |= 0x01; /* IO Capability Request */
524 events[6] |= 0x02; /* IO Capability Response */
525 events[6] |= 0x04; /* User Confirmation Request */
526 events[6] |= 0x08; /* User Passkey Request */
527 events[6] |= 0x10; /* Remote OOB Data Request */
528 events[6] |= 0x20; /* Simple Pairing Complete */
529 events[7] |= 0x04; /* User Passkey Notification */
530 events[7] |= 0x08; /* Keypress Notification */
531 events[7] |= 0x10; /* Remote Host Supported
532 * Features Notification */
533 }
534
535 if (hdev->features[4] & LMP_LE)
536 events[7] |= 0x20; /* LE Meta-Event */
537
538 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
539}
540
Andre Guedese6100a22011-06-30 19:20:54 -0300541static void hci_set_le_support(struct hci_dev *hdev)
542{
543 struct hci_cp_write_le_host_supported cp;
544
545 memset(&cp, 0, sizeof(cp));
546
Johan Hedberg06199cf2012-02-22 16:37:11 +0200547 if (enable_le && test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
Andre Guedese6100a22011-06-30 19:20:54 -0300548 cp.le = 1;
549 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
550 }
551
552 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
553}
554
Johan Hedbergd5859e22011-01-25 01:19:58 +0200555static void hci_setup(struct hci_dev *hdev)
556{
Andrei Emeltchenkoe61ef4992011-12-19 16:31:27 +0200557 if (hdev->dev_type != HCI_BREDR)
558 return;
559
Johan Hedbergd5859e22011-01-25 01:19:58 +0200560 hci_setup_event_mask(hdev);
561
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +0200562 if (hdev->hci_ver > BLUETOOTH_VER_1_1)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200563 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
564
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200565 if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
566 test_bit(HCI_MGMT, &hdev->dev_flags)) {
567 struct hci_cp_write_local_name cp;
568
569 memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
570 hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(cp), &cp);
571 }
572
Johan Hedberg54d04db2012-02-22 15:47:48 +0200573 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
574 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
575 u8 mode = 0x01;
576 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE,
577 sizeof(mode), &mode);
578 } else {
579 struct hci_cp_write_eir cp;
580
581 memset(hdev->eir, 0, sizeof(hdev->eir));
582 memset(&cp, 0, sizeof(cp));
583
584 hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
585 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200586 }
587
588 if (hdev->features[3] & LMP_RSSI_INQ)
589 hci_setup_inquiry_mode(hdev);
590
591 if (hdev->features[7] & LMP_INQ_TX_PWR)
592 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300593
594 if (hdev->features[7] & LMP_EXTFEATURES) {
595 struct hci_cp_read_local_ext_features cp;
596
597 cp.page = 0x01;
598 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
599 sizeof(cp), &cp);
600 }
Andre Guedese6100a22011-06-30 19:20:54 -0300601
Johan Hedberg47990ea2012-02-22 11:58:37 +0200602 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags)) {
603 u8 enable = 1;
604 hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE,
605 sizeof(enable), &enable);
606 }
607
Andre Guedese6100a22011-06-30 19:20:54 -0300608 if (hdev->features[4] & LMP_LE)
609 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200610}
611
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200612static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
613{
614 struct hci_rp_read_local_version *rp = (void *) skb->data;
615
616 BT_DBG("%s status 0x%x", hdev->name, rp->status);
617
618 if (rp->status)
619 return;
620
621 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200622 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200623 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200624 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200625 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200626
627 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
628 hdev->manufacturer,
629 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200630
631 if (test_bit(HCI_INIT, &hdev->flags))
632 hci_setup(hdev);
633}
634
635static void hci_setup_link_policy(struct hci_dev *hdev)
636{
637 u16 link_policy = 0;
638
639 if (hdev->features[0] & LMP_RSWITCH)
640 link_policy |= HCI_LP_RSWITCH;
641 if (hdev->features[0] & LMP_HOLD)
642 link_policy |= HCI_LP_HOLD;
643 if (hdev->features[0] & LMP_SNIFF)
644 link_policy |= HCI_LP_SNIFF;
645 if (hdev->features[1] & LMP_PARK)
646 link_policy |= HCI_LP_PARK;
647
648 link_policy = cpu_to_le16(link_policy);
649 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
650 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200651}
652
653static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
654{
655 struct hci_rp_read_local_commands *rp = (void *) skb->data;
656
657 BT_DBG("%s status 0x%x", hdev->name, rp->status);
658
659 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200660 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200661
662 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200663
664 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
665 hci_setup_link_policy(hdev);
666
667done:
668 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200669}
670
671static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
672{
673 struct hci_rp_read_local_features *rp = (void *) skb->data;
674
675 BT_DBG("%s status 0x%x", hdev->name, rp->status);
676
677 if (rp->status)
678 return;
679
680 memcpy(hdev->features, rp->features, 8);
681
682 /* Adjust default settings according to features
683 * supported by device. */
684
685 if (hdev->features[0] & LMP_3SLOT)
686 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
687
688 if (hdev->features[0] & LMP_5SLOT)
689 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
690
691 if (hdev->features[1] & LMP_HV2) {
692 hdev->pkt_type |= (HCI_HV2);
693 hdev->esco_type |= (ESCO_HV2);
694 }
695
696 if (hdev->features[1] & LMP_HV3) {
697 hdev->pkt_type |= (HCI_HV3);
698 hdev->esco_type |= (ESCO_HV3);
699 }
700
701 if (hdev->features[3] & LMP_ESCO)
702 hdev->esco_type |= (ESCO_EV3);
703
704 if (hdev->features[4] & LMP_EV4)
705 hdev->esco_type |= (ESCO_EV4);
706
707 if (hdev->features[4] & LMP_EV5)
708 hdev->esco_type |= (ESCO_EV5);
709
Marcel Holtmannefc76882009-02-06 09:13:37 +0100710 if (hdev->features[5] & LMP_EDR_ESCO_2M)
711 hdev->esco_type |= (ESCO_2EV3);
712
713 if (hdev->features[5] & LMP_EDR_ESCO_3M)
714 hdev->esco_type |= (ESCO_3EV3);
715
716 if (hdev->features[5] & LMP_EDR_3S_ESCO)
717 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
718
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200719 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
720 hdev->features[0], hdev->features[1],
721 hdev->features[2], hdev->features[3],
722 hdev->features[4], hdev->features[5],
723 hdev->features[6], hdev->features[7]);
724}
725
Andre Guedes971e3a42011-06-30 19:20:52 -0300726static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
727 struct sk_buff *skb)
728{
729 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
730
731 BT_DBG("%s status 0x%x", hdev->name, rp->status);
732
733 if (rp->status)
734 return;
735
Andre Guedesb5b32b62011-12-30 10:34:04 -0300736 switch (rp->page) {
737 case 0:
738 memcpy(hdev->features, rp->features, 8);
739 break;
740 case 1:
741 memcpy(hdev->host_features, rp->features, 8);
742 break;
743 }
Andre Guedes971e3a42011-06-30 19:20:52 -0300744
745 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
746}
747
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200748static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
749 struct sk_buff *skb)
750{
751 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
752
753 BT_DBG("%s status 0x%x", hdev->name, rp->status);
754
755 if (rp->status)
756 return;
757
758 hdev->flow_ctl_mode = rp->mode;
759
760 hci_req_complete(hdev, HCI_OP_READ_FLOW_CONTROL_MODE, rp->status);
761}
762
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200763static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
764{
765 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
766
767 BT_DBG("%s status 0x%x", hdev->name, rp->status);
768
769 if (rp->status)
770 return;
771
772 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
773 hdev->sco_mtu = rp->sco_mtu;
774 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
775 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
776
777 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
778 hdev->sco_mtu = 64;
779 hdev->sco_pkts = 8;
780 }
781
782 hdev->acl_cnt = hdev->acl_pkts;
783 hdev->sco_cnt = hdev->sco_pkts;
784
785 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
786 hdev->acl_mtu, hdev->acl_pkts,
787 hdev->sco_mtu, hdev->sco_pkts);
788}
789
790static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
791{
792 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
793
794 BT_DBG("%s status 0x%x", hdev->name, rp->status);
795
796 if (!rp->status)
797 bacpy(&hdev->bdaddr, &rp->bdaddr);
798
Johan Hedberg23bb5762010-12-21 23:01:27 +0200799 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
800}
801
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200802static void hci_cc_read_data_block_size(struct hci_dev *hdev,
803 struct sk_buff *skb)
804{
805 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
806
807 BT_DBG("%s status 0x%x", hdev->name, rp->status);
808
809 if (rp->status)
810 return;
811
812 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
813 hdev->block_len = __le16_to_cpu(rp->block_len);
814 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
815
816 hdev->block_cnt = hdev->num_blocks;
817
818 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
819 hdev->block_cnt, hdev->block_len);
820
821 hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status);
822}
823
Johan Hedberg23bb5762010-12-21 23:01:27 +0200824static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
825{
826 __u8 status = *((__u8 *) skb->data);
827
828 BT_DBG("%s status 0x%x", hdev->name, status);
829
830 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200831}
832
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300833static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
834 struct sk_buff *skb)
835{
836 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
837
838 BT_DBG("%s status 0x%x", hdev->name, rp->status);
839
840 if (rp->status)
841 return;
842
843 hdev->amp_status = rp->amp_status;
844 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
845 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
846 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
847 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
848 hdev->amp_type = rp->amp_type;
849 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
850 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
851 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
852 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
853
854 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
855}
856
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200857static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
858 struct sk_buff *skb)
859{
860 __u8 status = *((__u8 *) skb->data);
861
862 BT_DBG("%s status 0x%x", hdev->name, status);
863
864 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
865}
866
Johan Hedbergd5859e22011-01-25 01:19:58 +0200867static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
868{
869 __u8 status = *((__u8 *) skb->data);
870
871 BT_DBG("%s status 0x%x", hdev->name, status);
872
873 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
874}
875
876static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
877 struct sk_buff *skb)
878{
879 __u8 status = *((__u8 *) skb->data);
880
881 BT_DBG("%s status 0x%x", hdev->name, status);
882
883 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
884}
885
886static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
887 struct sk_buff *skb)
888{
889 __u8 status = *((__u8 *) skb->data);
890
891 BT_DBG("%s status 0x%x", hdev->name, status);
892
893 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
894}
895
896static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
897{
898 __u8 status = *((__u8 *) skb->data);
899
900 BT_DBG("%s status 0x%x", hdev->name, status);
901
902 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
903}
904
Johan Hedberg980e1a52011-01-22 06:10:07 +0200905static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
906{
907 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
908 struct hci_cp_pin_code_reply *cp;
909 struct hci_conn *conn;
910
911 BT_DBG("%s status 0x%x", hdev->name, rp->status);
912
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200913 hci_dev_lock(hdev);
914
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200915 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200916 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200917
918 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200919 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200920
921 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
922 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200923 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200924
925 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
926 if (conn)
927 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200928
929unlock:
930 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200931}
932
933static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
934{
935 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
936
937 BT_DBG("%s status 0x%x", hdev->name, rp->status);
938
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200939 hci_dev_lock(hdev);
940
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200941 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200942 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200943 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200944
945 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200946}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200947
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300948static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
949 struct sk_buff *skb)
950{
951 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
952
953 BT_DBG("%s status 0x%x", hdev->name, rp->status);
954
955 if (rp->status)
956 return;
957
958 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
959 hdev->le_pkts = rp->le_max_pkt;
960
961 hdev->le_cnt = hdev->le_pkts;
962
963 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
964
965 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
966}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200967
Johan Hedberga5c29682011-02-19 12:05:57 -0300968static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
969{
970 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
971
972 BT_DBG("%s status 0x%x", hdev->name, rp->status);
973
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200974 hci_dev_lock(hdev);
975
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200976 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200977 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
978 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200979
980 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300981}
982
983static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
984 struct sk_buff *skb)
985{
986 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
987
988 BT_DBG("%s status 0x%x", hdev->name, rp->status);
989
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200990 hci_dev_lock(hdev);
991
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200992 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200993 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +0200994 ACL_LINK, 0,
Johan Hedberga5c29682011-02-19 12:05:57 -0300995 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200996
997 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300998}
999
Brian Gix1143d452011-11-23 08:28:34 -08001000static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
1001{
1002 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1003
1004 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1005
1006 hci_dev_lock(hdev);
1007
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001008 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02001009 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
1010 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -08001011
1012 hci_dev_unlock(hdev);
1013}
1014
1015static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
1016 struct sk_buff *skb)
1017{
1018 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
1019
1020 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1021
1022 hci_dev_lock(hdev);
1023
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001024 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -08001025 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg272d90d2012-02-09 15:26:12 +02001026 ACL_LINK, 0,
Brian Gix1143d452011-11-23 08:28:34 -08001027 rp->status);
1028
1029 hci_dev_unlock(hdev);
1030}
1031
Szymon Jancc35938b2011-03-22 13:12:21 +01001032static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
1033 struct sk_buff *skb)
1034{
1035 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
1036
1037 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1038
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001039 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001040 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +01001041 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001042 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +01001043}
1044
Andre Guedes07f7fa52011-12-02 21:13:31 +09001045static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb)
1046{
1047 __u8 status = *((__u8 *) skb->data);
1048
1049 BT_DBG("%s status 0x%x", hdev->name, status);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001050
1051 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status);
Andre Guedes3fd24152012-02-03 17:48:01 -03001052
1053 if (status) {
1054 hci_dev_lock(hdev);
1055 mgmt_start_discovery_failed(hdev, status);
1056 hci_dev_unlock(hdev);
1057 return;
1058 }
Andre Guedes07f7fa52011-12-02 21:13:31 +09001059}
1060
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001061static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
1062 struct sk_buff *skb)
1063{
1064 struct hci_cp_le_set_scan_enable *cp;
1065 __u8 status = *((__u8 *) skb->data);
1066
1067 BT_DBG("%s status 0x%x", hdev->name, status);
1068
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001069 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
1070 if (!cp)
1071 return;
1072
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001073 switch (cp->enable) {
1074 case LE_SCANNING_ENABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001075 hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_ENABLE, status);
1076
Andre Guedes3fd24152012-02-03 17:48:01 -03001077 if (status) {
1078 hci_dev_lock(hdev);
1079 mgmt_start_discovery_failed(hdev, status);
1080 hci_dev_unlock(hdev);
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001081 return;
Andre Guedes3fd24152012-02-03 17:48:01 -03001082 }
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001083
Andre Guedesd23264a2011-11-25 20:53:38 -03001084 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
1085
Gustavo F. Padovandb323f22011-06-20 16:39:29 -03001086 cancel_delayed_work_sync(&hdev->adv_work);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001087
1088 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001089 hci_adv_entries_clear(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001090 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Andre Guedesa8f13c82011-09-09 18:56:24 -03001091 hci_dev_unlock(hdev);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001092 break;
1093
1094 case LE_SCANNING_DISABLED:
Andre Guedes7ba8b4b2012-02-03 17:47:59 -03001095 if (status)
1096 return;
1097
Andre Guedesd23264a2011-11-25 20:53:38 -03001098 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
1099
Andre Guedesd0843292012-01-02 19:18:11 -03001100 schedule_delayed_work(&hdev->adv_work, ADV_CLEAR_TIMEOUT);
Andre Guedes5e0452c2012-02-17 20:39:38 -03001101
1102 if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED) {
1103 mgmt_interleaved_discovery(hdev);
1104 } else {
1105 hci_dev_lock(hdev);
1106 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1107 hci_dev_unlock(hdev);
1108 }
1109
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +02001110 break;
1111
1112 default:
1113 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
1114 break;
Andre Guedes35815082011-05-26 16:23:53 -03001115 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -03001116}
1117
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001118static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
1119{
1120 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
1121
1122 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1123
1124 if (rp->status)
1125 return;
1126
1127 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
1128}
1129
1130static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
1131{
1132 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
1133
1134 BT_DBG("%s status 0x%x", hdev->name, rp->status);
1135
1136 if (rp->status)
1137 return;
1138
1139 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
1140}
1141
Andre Guedesf9b49302011-06-30 19:20:53 -03001142static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
1143 struct sk_buff *skb)
1144{
1145 struct hci_cp_read_local_ext_features cp;
Johan Hedberg06199cf2012-02-22 16:37:11 +02001146 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -03001147 __u8 status = *((__u8 *) skb->data);
1148
1149 BT_DBG("%s status 0x%x", hdev->name, status);
1150
Johan Hedberg06199cf2012-02-22 16:37:11 +02001151 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
1152 if (sent && test_bit(HCI_MGMT, &hdev->dev_flags))
1153 mgmt_le_enable_complete(hdev, sent->le, status);
1154
Andre Guedesf9b49302011-06-30 19:20:53 -03001155 if (status)
1156 return;
1157
1158 cp.page = 0x01;
1159 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1160}
1161
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001162static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1163{
1164 BT_DBG("%s status 0x%x", hdev->name, status);
1165
1166 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001167 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001168 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001169 hci_dev_lock(hdev);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001170 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Andre Guedes7a135102011-11-09 17:14:25 -03001171 mgmt_start_discovery_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001172 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001173 return;
1174 }
1175
Andre Guedes89352e72011-11-04 14:16:53 -03001176 set_bit(HCI_INQUIRY, &hdev->flags);
1177
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001178 hci_dev_lock(hdev);
Andre Guedes343f9352012-02-17 20:39:37 -03001179 hci_discovery_set_state(hdev, DISCOVERY_FINDING);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001180 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001181}
1182
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1184{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001185 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001188 BT_DBG("%s status 0x%x", hdev->name, status);
1189
1190 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191 if (!cp)
1192 return;
1193
1194 hci_dev_lock(hdev);
1195
1196 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1197
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001198 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199
1200 if (status) {
1201 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001202 if (status != 0x0c || conn->attempt > 2) {
1203 conn->state = BT_CLOSED;
1204 hci_proto_connect_cfm(conn, status);
1205 hci_conn_del(conn);
1206 } else
1207 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 }
1209 } else {
1210 if (!conn) {
1211 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1212 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001213 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 conn->link_mode |= HCI_LM_MASTER;
1215 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001216 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217 }
1218 }
1219
1220 hci_dev_unlock(hdev);
1221}
1222
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001223static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001225 struct hci_cp_add_sco *cp;
1226 struct hci_conn *acl, *sco;
1227 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001229 BT_DBG("%s status 0x%x", hdev->name, status);
1230
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001231 if (!status)
1232 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001234 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1235 if (!cp)
1236 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001238 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001240 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001241
1242 hci_dev_lock(hdev);
1243
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001244 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001245 if (acl) {
1246 sco = acl->link;
1247 if (sco) {
1248 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001249
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001250 hci_proto_connect_cfm(sco, status);
1251 hci_conn_del(sco);
1252 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001253 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001254
1255 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256}
1257
Marcel Holtmannf8558552008-07-14 20:13:49 +02001258static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1259{
1260 struct hci_cp_auth_requested *cp;
1261 struct hci_conn *conn;
1262
1263 BT_DBG("%s status 0x%x", hdev->name, status);
1264
1265 if (!status)
1266 return;
1267
1268 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1269 if (!cp)
1270 return;
1271
1272 hci_dev_lock(hdev);
1273
1274 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1275 if (conn) {
1276 if (conn->state == BT_CONFIG) {
1277 hci_proto_connect_cfm(conn, status);
1278 hci_conn_put(conn);
1279 }
1280 }
1281
1282 hci_dev_unlock(hdev);
1283}
1284
1285static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1286{
1287 struct hci_cp_set_conn_encrypt *cp;
1288 struct hci_conn *conn;
1289
1290 BT_DBG("%s status 0x%x", hdev->name, status);
1291
1292 if (!status)
1293 return;
1294
1295 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1296 if (!cp)
1297 return;
1298
1299 hci_dev_lock(hdev);
1300
1301 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1302 if (conn) {
1303 if (conn->state == BT_CONFIG) {
1304 hci_proto_connect_cfm(conn, status);
1305 hci_conn_put(conn);
1306 }
1307 }
1308
1309 hci_dev_unlock(hdev);
1310}
1311
Johan Hedberg127178d2010-11-18 22:22:29 +02001312static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001313 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001314{
Johan Hedberg392599b2010-11-18 22:22:28 +02001315 if (conn->state != BT_CONFIG || !conn->out)
1316 return 0;
1317
Johan Hedberg765c2a92011-01-19 12:06:52 +05301318 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001319 return 0;
1320
1321 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001322 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001323 if (!hci_conn_ssp_enabled(conn) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001324 conn->pending_sec_level != BT_SECURITY_HIGH &&
1325 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001326 return 0;
1327
Johan Hedberg392599b2010-11-18 22:22:28 +02001328 return 1;
1329}
1330
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001331static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e)
1332{
1333 struct hci_cp_remote_name_req cp;
1334
1335 memset(&cp, 0, sizeof(cp));
1336
1337 bacpy(&cp.bdaddr, &e->data.bdaddr);
1338 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1339 cp.pscan_mode = e->data.pscan_mode;
1340 cp.clock_offset = e->data.clock_offset;
1341
1342 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1343}
1344
Johan Hedbergb644ba32012-01-17 21:48:47 +02001345static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001346{
1347 struct discovery_state *discov = &hdev->discovery;
1348 struct inquiry_entry *e;
1349
Johan Hedbergb644ba32012-01-17 21:48:47 +02001350 if (list_empty(&discov->resolve))
1351 return false;
1352
1353 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1354 if (hci_resolve_name(hdev, e) == 0) {
1355 e->name_state = NAME_PENDING;
1356 return true;
1357 }
1358
1359 return false;
1360}
1361
1362static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
1363 bdaddr_t *bdaddr, u8 *name, u8 name_len)
1364{
1365 struct discovery_state *discov = &hdev->discovery;
1366 struct inquiry_entry *e;
1367
1368 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
1369 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00,
1370 name, name_len, conn->dev_class);
1371
1372 if (discov->state == DISCOVERY_STOPPED)
1373 return;
1374
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001375 if (discov->state == DISCOVERY_STOPPING)
1376 goto discov_complete;
1377
1378 if (discov->state != DISCOVERY_RESOLVING)
1379 return;
1380
1381 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
1382 if (e) {
1383 e->name_state = NAME_KNOWN;
1384 list_del(&e->list);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001385 if (name)
1386 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1387 e->data.rssi, name, name_len);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001388 }
1389
Johan Hedbergb644ba32012-01-17 21:48:47 +02001390 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001391 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001392
1393discov_complete:
1394 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1395}
1396
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001397static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1398{
Johan Hedberg127178d2010-11-18 22:22:29 +02001399 struct hci_cp_remote_name_req *cp;
1400 struct hci_conn *conn;
1401
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001402 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001403
1404 /* If successful wait for the name req complete event before
1405 * checking for the need to do authentication */
1406 if (!status)
1407 return;
1408
1409 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1410 if (!cp)
1411 return;
1412
1413 hci_dev_lock(hdev);
1414
1415 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001416
1417 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1418 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1419
Johan Hedberg79c6c702011-04-28 11:28:55 -07001420 if (!conn)
1421 goto unlock;
1422
1423 if (!hci_outgoing_auth_needed(hdev, conn))
1424 goto unlock;
1425
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001426 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001427 struct hci_cp_auth_requested cp;
1428 cp.handle = __cpu_to_le16(conn->handle);
1429 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1430 }
1431
Johan Hedberg79c6c702011-04-28 11:28:55 -07001432unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001433 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001434}
1435
Marcel Holtmann769be972008-07-14 20:13:49 +02001436static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1437{
1438 struct hci_cp_read_remote_features *cp;
1439 struct hci_conn *conn;
1440
1441 BT_DBG("%s status 0x%x", hdev->name, status);
1442
1443 if (!status)
1444 return;
1445
1446 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1447 if (!cp)
1448 return;
1449
1450 hci_dev_lock(hdev);
1451
1452 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1453 if (conn) {
1454 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001455 hci_proto_connect_cfm(conn, status);
1456 hci_conn_put(conn);
1457 }
1458 }
1459
1460 hci_dev_unlock(hdev);
1461}
1462
1463static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1464{
1465 struct hci_cp_read_remote_ext_features *cp;
1466 struct hci_conn *conn;
1467
1468 BT_DBG("%s status 0x%x", hdev->name, status);
1469
1470 if (!status)
1471 return;
1472
1473 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1474 if (!cp)
1475 return;
1476
1477 hci_dev_lock(hdev);
1478
1479 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1480 if (conn) {
1481 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001482 hci_proto_connect_cfm(conn, status);
1483 hci_conn_put(conn);
1484 }
1485 }
1486
1487 hci_dev_unlock(hdev);
1488}
1489
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001490static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1491{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001492 struct hci_cp_setup_sync_conn *cp;
1493 struct hci_conn *acl, *sco;
1494 __u16 handle;
1495
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001496 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001497
1498 if (!status)
1499 return;
1500
1501 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1502 if (!cp)
1503 return;
1504
1505 handle = __le16_to_cpu(cp->handle);
1506
1507 BT_DBG("%s handle %d", hdev->name, handle);
1508
1509 hci_dev_lock(hdev);
1510
1511 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001512 if (acl) {
1513 sco = acl->link;
1514 if (sco) {
1515 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001516
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001517 hci_proto_connect_cfm(sco, status);
1518 hci_conn_del(sco);
1519 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001520 }
1521
1522 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001523}
1524
1525static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1526{
1527 struct hci_cp_sniff_mode *cp;
1528 struct hci_conn *conn;
1529
1530 BT_DBG("%s status 0x%x", hdev->name, status);
1531
1532 if (!status)
1533 return;
1534
1535 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1536 if (!cp)
1537 return;
1538
1539 hci_dev_lock(hdev);
1540
1541 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001542 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001543 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001544
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001545 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001546 hci_sco_setup(conn, status);
1547 }
1548
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001549 hci_dev_unlock(hdev);
1550}
1551
1552static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1553{
1554 struct hci_cp_exit_sniff_mode *cp;
1555 struct hci_conn *conn;
1556
1557 BT_DBG("%s status 0x%x", hdev->name, status);
1558
1559 if (!status)
1560 return;
1561
1562 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1563 if (!cp)
1564 return;
1565
1566 hci_dev_lock(hdev);
1567
1568 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001569 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001570 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001571
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001572 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001573 hci_sco_setup(conn, status);
1574 }
1575
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001576 hci_dev_unlock(hdev);
1577}
1578
Johan Hedberg88c3df12012-02-09 14:27:38 +02001579static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1580{
1581 struct hci_cp_disconnect *cp;
1582 struct hci_conn *conn;
1583
1584 if (!status)
1585 return;
1586
1587 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1588 if (!cp)
1589 return;
1590
1591 hci_dev_lock(hdev);
1592
1593 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1594 if (conn)
1595 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1596 conn->dst_type, status);
1597
1598 hci_dev_unlock(hdev);
1599}
1600
Ville Tervofcd89c02011-02-10 22:38:47 -03001601static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1602{
1603 struct hci_cp_le_create_conn *cp;
1604 struct hci_conn *conn;
1605
1606 BT_DBG("%s status 0x%x", hdev->name, status);
1607
1608 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1609 if (!cp)
1610 return;
1611
1612 hci_dev_lock(hdev);
1613
1614 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1615
1616 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1617 conn);
1618
1619 if (status) {
1620 if (conn && conn->state == BT_CONNECT) {
1621 conn->state = BT_CLOSED;
1622 hci_proto_connect_cfm(conn, status);
1623 hci_conn_del(conn);
1624 }
1625 } else {
1626 if (!conn) {
1627 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001628 if (conn) {
1629 conn->dst_type = cp->peer_addr_type;
Johan Hedberga0c808b2012-01-16 09:49:58 +02001630 conn->out = true;
Andre Guedes29b79882011-05-31 14:20:54 -03001631 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001632 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001633 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001634 }
1635 }
1636
1637 hci_dev_unlock(hdev);
1638}
1639
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001640static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1641{
1642 BT_DBG("%s status 0x%x", hdev->name, status);
1643}
1644
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001645static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1646{
1647 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001648 struct discovery_state *discov = &hdev->discovery;
1649 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001650
1651 BT_DBG("%s status %d", hdev->name, status);
1652
Johan Hedberg23bb5762010-12-21 23:01:27 +02001653 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001654
1655 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001656
1657 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1658 return;
1659
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001660 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001661 return;
1662
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001663 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001664
Andre Guedes343f9352012-02-17 20:39:37 -03001665 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001666 goto unlock;
1667
1668 if (list_empty(&discov->resolve)) {
1669 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1670 goto unlock;
1671 }
1672
1673 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1674 if (e && hci_resolve_name(hdev, e) == 0) {
1675 e->name_state = NAME_PENDING;
1676 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1677 } else {
1678 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1679 }
1680
1681unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001682 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001683}
1684
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1686{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001687 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001688 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 int num_rsp = *((__u8 *) skb->data);
1690
1691 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1692
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001693 if (!num_rsp)
1694 return;
1695
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001697
Johan Hedberge17acd42011-03-30 23:57:16 +03001698 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001699 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001700
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701 bacpy(&data.bdaddr, &info->bdaddr);
1702 data.pscan_rep_mode = info->pscan_rep_mode;
1703 data.pscan_period_mode = info->pscan_period_mode;
1704 data.pscan_mode = info->pscan_mode;
1705 memcpy(data.dev_class, info->dev_class, 3);
1706 data.clock_offset = info->clock_offset;
1707 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001708 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001709
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001710 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001711 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001712 info->dev_class, 0, !name_known, ssp,
Andre Guedes7d262f82012-01-10 18:20:49 -03001713 NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001715
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 hci_dev_unlock(hdev);
1717}
1718
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001719static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001721 struct hci_ev_conn_complete *ev = (void *) skb->data;
1722 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001724 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001725
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001727
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001728 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001729 if (!conn) {
1730 if (ev->link_type != SCO_LINK)
1731 goto unlock;
1732
1733 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1734 if (!conn)
1735 goto unlock;
1736
1737 conn->type = SCO_LINK;
1738 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001739
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001740 if (!ev->status) {
1741 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001742
1743 if (conn->type == ACL_LINK) {
1744 conn->state = BT_CONFIG;
1745 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001746 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001747 } else
1748 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001749
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001750 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001751 hci_conn_add_sysfs(conn);
1752
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001753 if (test_bit(HCI_AUTH, &hdev->flags))
1754 conn->link_mode |= HCI_LM_AUTH;
1755
1756 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1757 conn->link_mode |= HCI_LM_ENCRYPT;
1758
1759 /* Get remote features */
1760 if (conn->type == ACL_LINK) {
1761 struct hci_cp_read_remote_features cp;
1762 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001763 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1764 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001765 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001766
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001767 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001768 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001769 struct hci_cp_change_conn_ptype cp;
1770 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001771 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1772 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1773 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001774 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001775 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001776 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001777 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001778 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001779 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001780 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001781
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001782 if (conn->type == ACL_LINK)
1783 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001784
Marcel Holtmann769be972008-07-14 20:13:49 +02001785 if (ev->status) {
1786 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001787 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001788 } else if (ev->link_type != ACL_LINK)
1789 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001790
1791unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001793
1794 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795}
1796
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1798{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001799 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 int mask = hdev->link_mode;
1801
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001802 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1803 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804
1805 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1806
Szymon Janc138d22e2011-02-17 16:44:23 +01001807 if ((mask & HCI_LM_ACCEPT) &&
1808 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001810 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812
1813 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001814
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001815 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1816 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001817 memcpy(ie->data.dev_class, ev->dev_class, 3);
1818
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1820 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001821 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1822 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001823 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 hci_dev_unlock(hdev);
1825 return;
1826 }
1827 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001828
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 memcpy(conn->dev_class, ev->dev_class, 3);
1830 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001831
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 hci_dev_unlock(hdev);
1833
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001834 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1835 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001837 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001839 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1840 cp.role = 0x00; /* Become master */
1841 else
1842 cp.role = 0x01; /* Remain slave */
1843
1844 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1845 sizeof(cp), &cp);
1846 } else {
1847 struct hci_cp_accept_sync_conn_req cp;
1848
1849 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001850 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001851
1852 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1853 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1854 cp.max_latency = cpu_to_le16(0xffff);
1855 cp.content_format = cpu_to_le16(hdev->voice_setting);
1856 cp.retrans_effort = 0xff;
1857
1858 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1859 sizeof(cp), &cp);
1860 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861 } else {
1862 /* Connection rejected */
1863 struct hci_cp_reject_conn_req cp;
1864
1865 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001866 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001867 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 }
1869}
1870
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1872{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001873 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001874 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875
1876 BT_DBG("%s status %d", hdev->name, ev->status);
1877
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878 hci_dev_lock(hdev);
1879
Marcel Holtmann04837f62006-07-03 10:02:33 +02001880 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001881 if (!conn)
1882 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001883
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001884 if (ev->status == 0)
1885 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886
Johan Hedbergb644ba32012-01-17 21:48:47 +02001887 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
1888 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001889 if (ev->status != 0)
Johan Hedberg88c3df12012-02-09 14:27:38 +02001890 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
1891 conn->dst_type, ev->status);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001892 else
Johan Hedbergafc747a2012-01-15 18:11:07 +02001893 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Johan Hedberg48264f02011-11-09 13:58:58 +02001894 conn->dst_type);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001895 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001896
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001897 if (ev->status == 0) {
1898 hci_proto_disconn_cfm(conn, ev->reason);
1899 hci_conn_del(conn);
1900 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001901
1902unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903 hci_dev_unlock(hdev);
1904}
1905
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001906static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1907{
1908 struct hci_ev_auth_complete *ev = (void *) skb->data;
1909 struct hci_conn *conn;
1910
1911 BT_DBG("%s status %d", hdev->name, ev->status);
1912
1913 hci_dev_lock(hdev);
1914
1915 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001916 if (!conn)
1917 goto unlock;
1918
1919 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001920 if (!hci_conn_ssp_enabled(conn) &&
1921 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001922 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001923 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001924 conn->link_mode |= HCI_LM_AUTH;
1925 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001926 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001927 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001928 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
1929 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001930 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001931
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001932 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1933 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001934
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001935 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001936 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001937 struct hci_cp_set_conn_encrypt cp;
1938 cp.handle = ev->handle;
1939 cp.encrypt = 0x01;
1940 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1941 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001942 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001943 conn->state = BT_CONNECTED;
1944 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001945 hci_conn_put(conn);
1946 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001947 } else {
1948 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001949
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001950 hci_conn_hold(conn);
1951 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1952 hci_conn_put(conn);
1953 }
1954
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001955 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001956 if (!ev->status) {
1957 struct hci_cp_set_conn_encrypt cp;
1958 cp.handle = ev->handle;
1959 cp.encrypt = 0x01;
1960 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1961 &cp);
1962 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001963 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001964 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001965 }
1966 }
1967
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001968unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001969 hci_dev_unlock(hdev);
1970}
1971
1972static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1973{
Johan Hedberg127178d2010-11-18 22:22:29 +02001974 struct hci_ev_remote_name *ev = (void *) skb->data;
1975 struct hci_conn *conn;
1976
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001977 BT_DBG("%s", hdev->name);
1978
1979 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001980
1981 hci_dev_lock(hdev);
1982
1983 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001984
1985 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1986 goto check_auth;
1987
1988 if (ev->status == 0)
1989 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
1990 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
1991 else
1992 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1993
1994check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001995 if (!conn)
1996 goto unlock;
1997
1998 if (!hci_outgoing_auth_needed(hdev, conn))
1999 goto unlock;
2000
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002001 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002002 struct hci_cp_auth_requested cp;
2003 cp.handle = __cpu_to_le16(conn->handle);
2004 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
2005 }
2006
Johan Hedberg79c6c702011-04-28 11:28:55 -07002007unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02002008 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002009}
2010
2011static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2012{
2013 struct hci_ev_encrypt_change *ev = (void *) skb->data;
2014 struct hci_conn *conn;
2015
2016 BT_DBG("%s status %d", hdev->name, ev->status);
2017
2018 hci_dev_lock(hdev);
2019
2020 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2021 if (conn) {
2022 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002023 if (ev->encrypt) {
2024 /* Encryption implies authentication */
2025 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002026 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002027 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002028 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002029 conn->link_mode &= ~HCI_LM_ENCRYPT;
2030 }
2031
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002032 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002033
Marcel Holtmannf8558552008-07-14 20:13:49 +02002034 if (conn->state == BT_CONFIG) {
2035 if (!ev->status)
2036 conn->state = BT_CONNECTED;
2037
2038 hci_proto_connect_cfm(conn, ev->status);
2039 hci_conn_put(conn);
2040 } else
2041 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002042 }
2043
2044 hci_dev_unlock(hdev);
2045}
2046
2047static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2048{
2049 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2050 struct hci_conn *conn;
2051
2052 BT_DBG("%s status %d", hdev->name, ev->status);
2053
2054 hci_dev_lock(hdev);
2055
2056 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2057 if (conn) {
2058 if (!ev->status)
2059 conn->link_mode |= HCI_LM_SECURE;
2060
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002061 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002062
2063 hci_key_change_cfm(conn, ev->status);
2064 }
2065
2066 hci_dev_unlock(hdev);
2067}
2068
2069static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2070{
2071 struct hci_ev_remote_features *ev = (void *) skb->data;
2072 struct hci_conn *conn;
2073
2074 BT_DBG("%s status %d", hdev->name, ev->status);
2075
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002076 hci_dev_lock(hdev);
2077
2078 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002079 if (!conn)
2080 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002081
Johan Hedbergccd556f2010-11-10 17:11:51 +02002082 if (!ev->status)
2083 memcpy(conn->features, ev->features, 8);
2084
2085 if (conn->state != BT_CONFIG)
2086 goto unlock;
2087
2088 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2089 struct hci_cp_read_remote_ext_features cp;
2090 cp.handle = ev->handle;
2091 cp.page = 0x01;
2092 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02002093 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002094 goto unlock;
2095 }
2096
Johan Hedberg127178d2010-11-18 22:22:29 +02002097 if (!ev->status) {
2098 struct hci_cp_remote_name_req cp;
2099 memset(&cp, 0, sizeof(cp));
2100 bacpy(&cp.bdaddr, &conn->dst);
2101 cp.pscan_rep_mode = 0x02;
2102 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002103 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2104 mgmt_device_connected(hdev, &conn->dst, conn->type,
2105 conn->dst_type, NULL, 0,
2106 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002107
Johan Hedberg127178d2010-11-18 22:22:29 +02002108 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002109 conn->state = BT_CONNECTED;
2110 hci_proto_connect_cfm(conn, ev->status);
2111 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002112 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002113
Johan Hedbergccd556f2010-11-10 17:11:51 +02002114unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002115 hci_dev_unlock(hdev);
2116}
2117
2118static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
2119{
2120 BT_DBG("%s", hdev->name);
2121}
2122
2123static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2124{
2125 BT_DBG("%s", hdev->name);
2126}
2127
2128static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2129{
2130 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2131 __u16 opcode;
2132
2133 skb_pull(skb, sizeof(*ev));
2134
2135 opcode = __le16_to_cpu(ev->opcode);
2136
2137 switch (opcode) {
2138 case HCI_OP_INQUIRY_CANCEL:
2139 hci_cc_inquiry_cancel(hdev, skb);
2140 break;
2141
2142 case HCI_OP_EXIT_PERIODIC_INQ:
2143 hci_cc_exit_periodic_inq(hdev, skb);
2144 break;
2145
2146 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2147 hci_cc_remote_name_req_cancel(hdev, skb);
2148 break;
2149
2150 case HCI_OP_ROLE_DISCOVERY:
2151 hci_cc_role_discovery(hdev, skb);
2152 break;
2153
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002154 case HCI_OP_READ_LINK_POLICY:
2155 hci_cc_read_link_policy(hdev, skb);
2156 break;
2157
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002158 case HCI_OP_WRITE_LINK_POLICY:
2159 hci_cc_write_link_policy(hdev, skb);
2160 break;
2161
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002162 case HCI_OP_READ_DEF_LINK_POLICY:
2163 hci_cc_read_def_link_policy(hdev, skb);
2164 break;
2165
2166 case HCI_OP_WRITE_DEF_LINK_POLICY:
2167 hci_cc_write_def_link_policy(hdev, skb);
2168 break;
2169
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002170 case HCI_OP_RESET:
2171 hci_cc_reset(hdev, skb);
2172 break;
2173
2174 case HCI_OP_WRITE_LOCAL_NAME:
2175 hci_cc_write_local_name(hdev, skb);
2176 break;
2177
2178 case HCI_OP_READ_LOCAL_NAME:
2179 hci_cc_read_local_name(hdev, skb);
2180 break;
2181
2182 case HCI_OP_WRITE_AUTH_ENABLE:
2183 hci_cc_write_auth_enable(hdev, skb);
2184 break;
2185
2186 case HCI_OP_WRITE_ENCRYPT_MODE:
2187 hci_cc_write_encrypt_mode(hdev, skb);
2188 break;
2189
2190 case HCI_OP_WRITE_SCAN_ENABLE:
2191 hci_cc_write_scan_enable(hdev, skb);
2192 break;
2193
2194 case HCI_OP_READ_CLASS_OF_DEV:
2195 hci_cc_read_class_of_dev(hdev, skb);
2196 break;
2197
2198 case HCI_OP_WRITE_CLASS_OF_DEV:
2199 hci_cc_write_class_of_dev(hdev, skb);
2200 break;
2201
2202 case HCI_OP_READ_VOICE_SETTING:
2203 hci_cc_read_voice_setting(hdev, skb);
2204 break;
2205
2206 case HCI_OP_WRITE_VOICE_SETTING:
2207 hci_cc_write_voice_setting(hdev, skb);
2208 break;
2209
2210 case HCI_OP_HOST_BUFFER_SIZE:
2211 hci_cc_host_buffer_size(hdev, skb);
2212 break;
2213
Marcel Holtmann333140b2008-07-14 20:13:48 +02002214 case HCI_OP_WRITE_SSP_MODE:
2215 hci_cc_write_ssp_mode(hdev, skb);
2216 break;
2217
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002218 case HCI_OP_READ_LOCAL_VERSION:
2219 hci_cc_read_local_version(hdev, skb);
2220 break;
2221
2222 case HCI_OP_READ_LOCAL_COMMANDS:
2223 hci_cc_read_local_commands(hdev, skb);
2224 break;
2225
2226 case HCI_OP_READ_LOCAL_FEATURES:
2227 hci_cc_read_local_features(hdev, skb);
2228 break;
2229
Andre Guedes971e3a42011-06-30 19:20:52 -03002230 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2231 hci_cc_read_local_ext_features(hdev, skb);
2232 break;
2233
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002234 case HCI_OP_READ_BUFFER_SIZE:
2235 hci_cc_read_buffer_size(hdev, skb);
2236 break;
2237
2238 case HCI_OP_READ_BD_ADDR:
2239 hci_cc_read_bd_addr(hdev, skb);
2240 break;
2241
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002242 case HCI_OP_READ_DATA_BLOCK_SIZE:
2243 hci_cc_read_data_block_size(hdev, skb);
2244 break;
2245
Johan Hedberg23bb5762010-12-21 23:01:27 +02002246 case HCI_OP_WRITE_CA_TIMEOUT:
2247 hci_cc_write_ca_timeout(hdev, skb);
2248 break;
2249
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002250 case HCI_OP_READ_FLOW_CONTROL_MODE:
2251 hci_cc_read_flow_control_mode(hdev, skb);
2252 break;
2253
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002254 case HCI_OP_READ_LOCAL_AMP_INFO:
2255 hci_cc_read_local_amp_info(hdev, skb);
2256 break;
2257
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002258 case HCI_OP_DELETE_STORED_LINK_KEY:
2259 hci_cc_delete_stored_link_key(hdev, skb);
2260 break;
2261
Johan Hedbergd5859e22011-01-25 01:19:58 +02002262 case HCI_OP_SET_EVENT_MASK:
2263 hci_cc_set_event_mask(hdev, skb);
2264 break;
2265
2266 case HCI_OP_WRITE_INQUIRY_MODE:
2267 hci_cc_write_inquiry_mode(hdev, skb);
2268 break;
2269
2270 case HCI_OP_READ_INQ_RSP_TX_POWER:
2271 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2272 break;
2273
2274 case HCI_OP_SET_EVENT_FLT:
2275 hci_cc_set_event_flt(hdev, skb);
2276 break;
2277
Johan Hedberg980e1a52011-01-22 06:10:07 +02002278 case HCI_OP_PIN_CODE_REPLY:
2279 hci_cc_pin_code_reply(hdev, skb);
2280 break;
2281
2282 case HCI_OP_PIN_CODE_NEG_REPLY:
2283 hci_cc_pin_code_neg_reply(hdev, skb);
2284 break;
2285
Szymon Jancc35938b2011-03-22 13:12:21 +01002286 case HCI_OP_READ_LOCAL_OOB_DATA:
2287 hci_cc_read_local_oob_data_reply(hdev, skb);
2288 break;
2289
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002290 case HCI_OP_LE_READ_BUFFER_SIZE:
2291 hci_cc_le_read_buffer_size(hdev, skb);
2292 break;
2293
Johan Hedberga5c29682011-02-19 12:05:57 -03002294 case HCI_OP_USER_CONFIRM_REPLY:
2295 hci_cc_user_confirm_reply(hdev, skb);
2296 break;
2297
2298 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2299 hci_cc_user_confirm_neg_reply(hdev, skb);
2300 break;
2301
Brian Gix1143d452011-11-23 08:28:34 -08002302 case HCI_OP_USER_PASSKEY_REPLY:
2303 hci_cc_user_passkey_reply(hdev, skb);
2304 break;
2305
2306 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2307 hci_cc_user_passkey_neg_reply(hdev, skb);
Andre Guedes07f7fa52011-12-02 21:13:31 +09002308
2309 case HCI_OP_LE_SET_SCAN_PARAM:
2310 hci_cc_le_set_scan_param(hdev, skb);
Brian Gix1143d452011-11-23 08:28:34 -08002311 break;
2312
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002313 case HCI_OP_LE_SET_SCAN_ENABLE:
2314 hci_cc_le_set_scan_enable(hdev, skb);
2315 break;
2316
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002317 case HCI_OP_LE_LTK_REPLY:
2318 hci_cc_le_ltk_reply(hdev, skb);
2319 break;
2320
2321 case HCI_OP_LE_LTK_NEG_REPLY:
2322 hci_cc_le_ltk_neg_reply(hdev, skb);
2323 break;
2324
Andre Guedesf9b49302011-06-30 19:20:53 -03002325 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2326 hci_cc_write_le_host_supported(hdev, skb);
2327 break;
2328
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002329 default:
2330 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2331 break;
2332 }
2333
Ville Tervo6bd32322011-02-16 16:32:41 +02002334 if (ev->opcode != HCI_OP_NOP)
2335 del_timer(&hdev->cmd_timer);
2336
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002337 if (ev->ncmd) {
2338 atomic_set(&hdev->cmd_cnt, 1);
2339 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002340 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002341 }
2342}
2343
2344static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2345{
2346 struct hci_ev_cmd_status *ev = (void *) skb->data;
2347 __u16 opcode;
2348
2349 skb_pull(skb, sizeof(*ev));
2350
2351 opcode = __le16_to_cpu(ev->opcode);
2352
2353 switch (opcode) {
2354 case HCI_OP_INQUIRY:
2355 hci_cs_inquiry(hdev, ev->status);
2356 break;
2357
2358 case HCI_OP_CREATE_CONN:
2359 hci_cs_create_conn(hdev, ev->status);
2360 break;
2361
2362 case HCI_OP_ADD_SCO:
2363 hci_cs_add_sco(hdev, ev->status);
2364 break;
2365
Marcel Holtmannf8558552008-07-14 20:13:49 +02002366 case HCI_OP_AUTH_REQUESTED:
2367 hci_cs_auth_requested(hdev, ev->status);
2368 break;
2369
2370 case HCI_OP_SET_CONN_ENCRYPT:
2371 hci_cs_set_conn_encrypt(hdev, ev->status);
2372 break;
2373
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002374 case HCI_OP_REMOTE_NAME_REQ:
2375 hci_cs_remote_name_req(hdev, ev->status);
2376 break;
2377
Marcel Holtmann769be972008-07-14 20:13:49 +02002378 case HCI_OP_READ_REMOTE_FEATURES:
2379 hci_cs_read_remote_features(hdev, ev->status);
2380 break;
2381
2382 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2383 hci_cs_read_remote_ext_features(hdev, ev->status);
2384 break;
2385
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002386 case HCI_OP_SETUP_SYNC_CONN:
2387 hci_cs_setup_sync_conn(hdev, ev->status);
2388 break;
2389
2390 case HCI_OP_SNIFF_MODE:
2391 hci_cs_sniff_mode(hdev, ev->status);
2392 break;
2393
2394 case HCI_OP_EXIT_SNIFF_MODE:
2395 hci_cs_exit_sniff_mode(hdev, ev->status);
2396 break;
2397
Johan Hedberg8962ee72011-01-20 12:40:27 +02002398 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002399 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002400 break;
2401
Ville Tervofcd89c02011-02-10 22:38:47 -03002402 case HCI_OP_LE_CREATE_CONN:
2403 hci_cs_le_create_conn(hdev, ev->status);
2404 break;
2405
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002406 case HCI_OP_LE_START_ENC:
2407 hci_cs_le_start_enc(hdev, ev->status);
2408 break;
2409
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002410 default:
2411 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2412 break;
2413 }
2414
Ville Tervo6bd32322011-02-16 16:32:41 +02002415 if (ev->opcode != HCI_OP_NOP)
2416 del_timer(&hdev->cmd_timer);
2417
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002418 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002419 atomic_set(&hdev->cmd_cnt, 1);
2420 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002421 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002422 }
2423}
2424
2425static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2426{
2427 struct hci_ev_role_change *ev = (void *) skb->data;
2428 struct hci_conn *conn;
2429
2430 BT_DBG("%s status %d", hdev->name, ev->status);
2431
2432 hci_dev_lock(hdev);
2433
2434 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2435 if (conn) {
2436 if (!ev->status) {
2437 if (ev->role)
2438 conn->link_mode &= ~HCI_LM_MASTER;
2439 else
2440 conn->link_mode |= HCI_LM_MASTER;
2441 }
2442
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002443 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002444
2445 hci_role_switch_cfm(conn, ev->status, ev->role);
2446 }
2447
2448 hci_dev_unlock(hdev);
2449}
2450
Linus Torvalds1da177e2005-04-16 15:20:36 -07002451static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2452{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002453 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002454 int i;
2455
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002456 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2457 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2458 return;
2459 }
2460
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002461 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2462 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002463 BT_DBG("%s bad parameters", hdev->name);
2464 return;
2465 }
2466
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002467 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2468
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002469 for (i = 0; i < ev->num_hndl; i++) {
2470 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002471 struct hci_conn *conn;
2472 __u16 handle, count;
2473
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002474 handle = __le16_to_cpu(info->handle);
2475 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002476
2477 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002478 if (!conn)
2479 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002480
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002481 conn->sent -= count;
2482
2483 switch (conn->type) {
2484 case ACL_LINK:
2485 hdev->acl_cnt += count;
2486 if (hdev->acl_cnt > hdev->acl_pkts)
2487 hdev->acl_cnt = hdev->acl_pkts;
2488 break;
2489
2490 case LE_LINK:
2491 if (hdev->le_pkts) {
2492 hdev->le_cnt += count;
2493 if (hdev->le_cnt > hdev->le_pkts)
2494 hdev->le_cnt = hdev->le_pkts;
2495 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002496 hdev->acl_cnt += count;
2497 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002498 hdev->acl_cnt = hdev->acl_pkts;
2499 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002500 break;
2501
2502 case SCO_LINK:
2503 hdev->sco_cnt += count;
2504 if (hdev->sco_cnt > hdev->sco_pkts)
2505 hdev->sco_cnt = hdev->sco_pkts;
2506 break;
2507
2508 default:
2509 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2510 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002511 }
2512 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002513
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002514 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515}
2516
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002517static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2518 struct sk_buff *skb)
2519{
2520 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2521 int i;
2522
2523 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2524 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2525 return;
2526 }
2527
2528 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
2529 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
2530 BT_DBG("%s bad parameters", hdev->name);
2531 return;
2532 }
2533
2534 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
2535 ev->num_hndl);
2536
2537 for (i = 0; i < ev->num_hndl; i++) {
2538 struct hci_comp_blocks_info *info = &ev->handles[i];
2539 struct hci_conn *conn;
2540 __u16 handle, block_count;
2541
2542 handle = __le16_to_cpu(info->handle);
2543 block_count = __le16_to_cpu(info->blocks);
2544
2545 conn = hci_conn_hash_lookup_handle(hdev, handle);
2546 if (!conn)
2547 continue;
2548
2549 conn->sent -= block_count;
2550
2551 switch (conn->type) {
2552 case ACL_LINK:
2553 hdev->block_cnt += block_count;
2554 if (hdev->block_cnt > hdev->num_blocks)
2555 hdev->block_cnt = hdev->num_blocks;
2556 break;
2557
2558 default:
2559 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2560 break;
2561 }
2562 }
2563
2564 queue_work(hdev->workqueue, &hdev->tx_work);
2565}
2566
Marcel Holtmann04837f62006-07-03 10:02:33 +02002567static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002569 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002570 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002571
2572 BT_DBG("%s status %d", hdev->name, ev->status);
2573
2574 hci_dev_lock(hdev);
2575
Marcel Holtmann04837f62006-07-03 10:02:33 +02002576 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2577 if (conn) {
2578 conn->mode = ev->mode;
2579 conn->interval = __le16_to_cpu(ev->interval);
2580
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002581 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002582 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002583 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002584 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002585 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002586 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002587
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002588 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002589 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002590 }
2591
2592 hci_dev_unlock(hdev);
2593}
2594
Linus Torvalds1da177e2005-04-16 15:20:36 -07002595static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2596{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002597 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2598 struct hci_conn *conn;
2599
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002600 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002601
2602 hci_dev_lock(hdev);
2603
2604 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002605 if (!conn)
2606 goto unlock;
2607
2608 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002609 hci_conn_hold(conn);
2610 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2611 hci_conn_put(conn);
2612 }
2613
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002614 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002615 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2616 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002617 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002618 u8 secure;
2619
2620 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2621 secure = 1;
2622 else
2623 secure = 0;
2624
Johan Hedberg744cf192011-11-08 20:40:14 +02002625 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002626 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002627
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002628unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002629 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002630}
2631
Linus Torvalds1da177e2005-04-16 15:20:36 -07002632static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2633{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002634 struct hci_ev_link_key_req *ev = (void *) skb->data;
2635 struct hci_cp_link_key_reply cp;
2636 struct hci_conn *conn;
2637 struct link_key *key;
2638
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002639 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002640
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002641 if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002642 return;
2643
2644 hci_dev_lock(hdev);
2645
2646 key = hci_find_link_key(hdev, &ev->bdaddr);
2647 if (!key) {
2648 BT_DBG("%s link key not found for %s", hdev->name,
2649 batostr(&ev->bdaddr));
2650 goto not_found;
2651 }
2652
2653 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2654 batostr(&ev->bdaddr));
2655
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002656 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002657 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002658 BT_DBG("%s ignoring debug key", hdev->name);
2659 goto not_found;
2660 }
2661
2662 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002663 if (conn) {
2664 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2665 conn->auth_type != 0xff &&
2666 (conn->auth_type & 0x01)) {
2667 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2668 goto not_found;
2669 }
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002670
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002671 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2672 conn->pending_sec_level == BT_SECURITY_HIGH) {
2673 BT_DBG("%s ignoring key unauthenticated for high \
2674 security", hdev->name);
2675 goto not_found;
2676 }
2677
2678 conn->key_type = key->type;
2679 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002680 }
2681
2682 bacpy(&cp.bdaddr, &ev->bdaddr);
2683 memcpy(cp.link_key, key->val, 16);
2684
2685 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2686
2687 hci_dev_unlock(hdev);
2688
2689 return;
2690
2691not_found:
2692 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2693 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002694}
2695
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2697{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002698 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2699 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002700 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002701
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002702 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002703
2704 hci_dev_lock(hdev);
2705
2706 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2707 if (conn) {
2708 hci_conn_hold(conn);
2709 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002710 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002711
2712 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2713 conn->key_type = ev->key_type;
2714
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002715 hci_conn_put(conn);
2716 }
2717
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002718 if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002719 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002720 ev->key_type, pin_len);
2721
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002722 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723}
2724
Marcel Holtmann04837f62006-07-03 10:02:33 +02002725static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2726{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002727 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002728 struct hci_conn *conn;
2729
2730 BT_DBG("%s status %d", hdev->name, ev->status);
2731
2732 hci_dev_lock(hdev);
2733
2734 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002735 if (conn && !ev->status) {
2736 struct inquiry_entry *ie;
2737
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002738 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2739 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002740 ie->data.clock_offset = ev->clock_offset;
2741 ie->timestamp = jiffies;
2742 }
2743 }
2744
2745 hci_dev_unlock(hdev);
2746}
2747
Marcel Holtmanna8746412008-07-14 20:13:46 +02002748static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2749{
2750 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2751 struct hci_conn *conn;
2752
2753 BT_DBG("%s status %d", hdev->name, ev->status);
2754
2755 hci_dev_lock(hdev);
2756
2757 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2758 if (conn && !ev->status)
2759 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2760
2761 hci_dev_unlock(hdev);
2762}
2763
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002764static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2765{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002766 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002767 struct inquiry_entry *ie;
2768
2769 BT_DBG("%s", hdev->name);
2770
2771 hci_dev_lock(hdev);
2772
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002773 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2774 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002775 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2776 ie->timestamp = jiffies;
2777 }
2778
2779 hci_dev_unlock(hdev);
2780}
2781
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002782static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2783{
2784 struct inquiry_data data;
2785 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002786 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002787
2788 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2789
2790 if (!num_rsp)
2791 return;
2792
2793 hci_dev_lock(hdev);
2794
2795 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002796 struct inquiry_info_with_rssi_and_pscan_mode *info;
2797 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002798
Johan Hedberge17acd42011-03-30 23:57:16 +03002799 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002800 bacpy(&data.bdaddr, &info->bdaddr);
2801 data.pscan_rep_mode = info->pscan_rep_mode;
2802 data.pscan_period_mode = info->pscan_period_mode;
2803 data.pscan_mode = info->pscan_mode;
2804 memcpy(data.dev_class, info->dev_class, 3);
2805 data.clock_offset = info->clock_offset;
2806 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002807 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002808
2809 name_known = hci_inquiry_cache_update(hdev, &data,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002810 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002811 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002812 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002813 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002814 }
2815 } else {
2816 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2817
Johan Hedberge17acd42011-03-30 23:57:16 +03002818 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002819 bacpy(&data.bdaddr, &info->bdaddr);
2820 data.pscan_rep_mode = info->pscan_rep_mode;
2821 data.pscan_period_mode = info->pscan_period_mode;
2822 data.pscan_mode = 0x00;
2823 memcpy(data.dev_class, info->dev_class, 3);
2824 data.clock_offset = info->clock_offset;
2825 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002826 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002827 name_known = hci_inquiry_cache_update(hdev, &data,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002828 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002829 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberge17acd42011-03-30 23:57:16 +03002830 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002831 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002832 }
2833 }
2834
2835 hci_dev_unlock(hdev);
2836}
2837
2838static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2839{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002840 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2841 struct hci_conn *conn;
2842
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002843 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002844
Marcel Holtmann41a96212008-07-14 20:13:48 +02002845 hci_dev_lock(hdev);
2846
2847 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002848 if (!conn)
2849 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002850
Johan Hedbergccd556f2010-11-10 17:11:51 +02002851 if (!ev->status && ev->page == 0x01) {
2852 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002853
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002854 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2855 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002856 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002857
Johan Hedberg58a681e2012-01-16 06:47:28 +02002858 if (ev->features[0] & 0x01)
2859 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002860 }
2861
Johan Hedbergccd556f2010-11-10 17:11:51 +02002862 if (conn->state != BT_CONFIG)
2863 goto unlock;
2864
Johan Hedberg127178d2010-11-18 22:22:29 +02002865 if (!ev->status) {
2866 struct hci_cp_remote_name_req cp;
2867 memset(&cp, 0, sizeof(cp));
2868 bacpy(&cp.bdaddr, &conn->dst);
2869 cp.pscan_rep_mode = 0x02;
2870 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002871 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2872 mgmt_device_connected(hdev, &conn->dst, conn->type,
2873 conn->dst_type, NULL, 0,
2874 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002875
Johan Hedberg127178d2010-11-18 22:22:29 +02002876 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002877 conn->state = BT_CONNECTED;
2878 hci_proto_connect_cfm(conn, ev->status);
2879 hci_conn_put(conn);
2880 }
2881
2882unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002883 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002884}
2885
2886static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2887{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002888 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2889 struct hci_conn *conn;
2890
2891 BT_DBG("%s status %d", hdev->name, ev->status);
2892
2893 hci_dev_lock(hdev);
2894
2895 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002896 if (!conn) {
2897 if (ev->link_type == ESCO_LINK)
2898 goto unlock;
2899
2900 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2901 if (!conn)
2902 goto unlock;
2903
2904 conn->type = SCO_LINK;
2905 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002906
Marcel Holtmann732547f2009-04-19 19:14:14 +02002907 switch (ev->status) {
2908 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002909 conn->handle = __le16_to_cpu(ev->handle);
2910 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002911
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002912 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002913 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002914 break;
2915
Stephen Coe705e5712010-02-16 11:29:44 -05002916 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002917 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002918 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002919 case 0x1f: /* Unspecified error */
2920 if (conn->out && conn->attempt < 2) {
2921 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2922 (hdev->esco_type & EDR_ESCO_MASK);
2923 hci_setup_sync(conn, conn->link->handle);
2924 goto unlock;
2925 }
2926 /* fall through */
2927
2928 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002929 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002930 break;
2931 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002932
2933 hci_proto_connect_cfm(conn, ev->status);
2934 if (ev->status)
2935 hci_conn_del(conn);
2936
2937unlock:
2938 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002939}
2940
2941static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2942{
2943 BT_DBG("%s", hdev->name);
2944}
2945
Marcel Holtmann04837f62006-07-03 10:02:33 +02002946static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2947{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002948 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002949
2950 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002951}
2952
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002953static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2954{
2955 struct inquiry_data data;
2956 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2957 int num_rsp = *((__u8 *) skb->data);
2958
2959 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2960
2961 if (!num_rsp)
2962 return;
2963
2964 hci_dev_lock(hdev);
2965
Johan Hedberge17acd42011-03-30 23:57:16 +03002966 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002967 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002968
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002969 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002970 data.pscan_rep_mode = info->pscan_rep_mode;
2971 data.pscan_period_mode = info->pscan_period_mode;
2972 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002973 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002974 data.clock_offset = info->clock_offset;
2975 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002976 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02002977
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002978 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02002979 name_known = eir_has_data_type(info->data,
2980 sizeof(info->data),
2981 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02002982 else
2983 name_known = true;
2984
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002985 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
2986 &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002987 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Johan Hedberg561aafb2012-01-04 13:31:59 +02002988 info->dev_class, info->rssi,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002989 !name_known, ssp, info->data,
Andre Guedes7d262f82012-01-10 18:20:49 -03002990 sizeof(info->data));
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002991 }
2992
2993 hci_dev_unlock(hdev);
2994}
2995
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002996static inline u8 hci_get_auth_req(struct hci_conn *conn)
2997{
2998 /* If remote requests dedicated bonding follow that lead */
2999 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
3000 /* If both remote and local IO capabilities allow MITM
3001 * protection then require it, otherwise don't */
3002 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
3003 return 0x02;
3004 else
3005 return 0x03;
3006 }
3007
3008 /* If remote requests no-bonding follow that lead */
3009 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003010 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003011
3012 return conn->auth_type;
3013}
3014
Marcel Holtmann04936842008-07-14 20:13:48 +02003015static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
3016{
3017 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3018 struct hci_conn *conn;
3019
3020 BT_DBG("%s", hdev->name);
3021
3022 hci_dev_lock(hdev);
3023
3024 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003025 if (!conn)
3026 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003027
Johan Hedberg03b555e2011-01-04 15:40:05 +02003028 hci_conn_hold(conn);
3029
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003030 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003031 goto unlock;
3032
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003033 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Johan Hedberg03b555e2011-01-04 15:40:05 +02003034 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003035 struct hci_cp_io_capability_reply cp;
3036
3037 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303038 /* Change the IO capability from KeyboardDisplay
3039 * to DisplayYesNo as it is not supported by BT spec. */
3040 cp.capability = (conn->io_capability == 0x04) ?
3041 0x01 : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003042 conn->auth_type = hci_get_auth_req(conn);
3043 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003044
Johan Hedberg58a681e2012-01-16 06:47:28 +02003045 if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) &&
Szymon Jancce85ee12011-03-22 13:12:23 +01003046 hci_find_remote_oob_data(hdev, &conn->dst))
3047 cp.oob_data = 0x01;
3048 else
3049 cp.oob_data = 0x00;
3050
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003051 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
3052 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003053 } else {
3054 struct hci_cp_io_capability_neg_reply cp;
3055
3056 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003057 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003058
3059 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
3060 sizeof(cp), &cp);
3061 }
3062
3063unlock:
3064 hci_dev_unlock(hdev);
3065}
3066
3067static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
3068{
3069 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3070 struct hci_conn *conn;
3071
3072 BT_DBG("%s", hdev->name);
3073
3074 hci_dev_lock(hdev);
3075
3076 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3077 if (!conn)
3078 goto unlock;
3079
Johan Hedberg03b555e2011-01-04 15:40:05 +02003080 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003081 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003082 if (ev->oob_data)
3083 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003084
3085unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003086 hci_dev_unlock(hdev);
3087}
3088
Johan Hedberga5c29682011-02-19 12:05:57 -03003089static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
3090 struct sk_buff *skb)
3091{
3092 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003093 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003094 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003095
3096 BT_DBG("%s", hdev->name);
3097
3098 hci_dev_lock(hdev);
3099
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003100 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003101 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003102
Johan Hedberg7a828902011-04-28 11:28:53 -07003103 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3104 if (!conn)
3105 goto unlock;
3106
3107 loc_mitm = (conn->auth_type & 0x01);
3108 rem_mitm = (conn->remote_auth & 0x01);
3109
3110 /* If we require MITM but the remote device can't provide that
3111 * (it has NoInputNoOutput) then reject the confirmation
3112 * request. The only exception is when we're dedicated bonding
3113 * initiators (connect_cfm_cb set) since then we always have the MITM
3114 * bit set. */
3115 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
3116 BT_DBG("Rejecting request: remote device can't provide MITM");
3117 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
3118 sizeof(ev->bdaddr), &ev->bdaddr);
3119 goto unlock;
3120 }
3121
3122 /* If no side requires MITM protection; auto-accept */
3123 if ((!loc_mitm || conn->remote_cap == 0x03) &&
3124 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003125
3126 /* If we're not the initiators request authorization to
3127 * proceed from user space (mgmt_user_confirm with
3128 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003129 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003130 BT_DBG("Confirming auto-accept as acceptor");
3131 confirm_hint = 1;
3132 goto confirm;
3133 }
3134
Johan Hedberg9f616562011-04-28 11:28:54 -07003135 BT_DBG("Auto-accept of user confirmation with %ums delay",
3136 hdev->auto_accept_delay);
3137
3138 if (hdev->auto_accept_delay > 0) {
3139 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3140 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3141 goto unlock;
3142 }
3143
Johan Hedberg7a828902011-04-28 11:28:53 -07003144 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
3145 sizeof(ev->bdaddr), &ev->bdaddr);
3146 goto unlock;
3147 }
3148
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003149confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003150 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003151 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003152
3153unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003154 hci_dev_unlock(hdev);
3155}
3156
Brian Gix1143d452011-11-23 08:28:34 -08003157static inline void hci_user_passkey_request_evt(struct hci_dev *hdev,
3158 struct sk_buff *skb)
3159{
3160 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3161
3162 BT_DBG("%s", hdev->name);
3163
3164 hci_dev_lock(hdev);
3165
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003166 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003167 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003168
3169 hci_dev_unlock(hdev);
3170}
3171
Marcel Holtmann04936842008-07-14 20:13:48 +02003172static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3173{
3174 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3175 struct hci_conn *conn;
3176
3177 BT_DBG("%s", hdev->name);
3178
3179 hci_dev_lock(hdev);
3180
3181 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003182 if (!conn)
3183 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003184
Johan Hedberg2a611692011-02-19 12:06:00 -03003185 /* To avoid duplicate auth_failed events to user space we check
3186 * the HCI_CONN_AUTH_PEND flag which will be set if we
3187 * initiated the authentication. A traditional auth_complete
3188 * event gets always produced as initiator and is also mapped to
3189 * the mgmt_auth_failed event */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003190 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status != 0)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003191 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
3192 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003193
3194 hci_conn_put(conn);
3195
3196unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003197 hci_dev_unlock(hdev);
3198}
3199
Marcel Holtmann41a96212008-07-14 20:13:48 +02003200static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
3201{
3202 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3203 struct inquiry_entry *ie;
3204
3205 BT_DBG("%s", hdev->name);
3206
3207 hci_dev_lock(hdev);
3208
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003209 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3210 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003211 ie->data.ssp_mode = (ev->features[0] & 0x01);
3212
3213 hci_dev_unlock(hdev);
3214}
3215
Szymon Janc2763eda2011-03-22 13:12:22 +01003216static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3217 struct sk_buff *skb)
3218{
3219 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3220 struct oob_data *data;
3221
3222 BT_DBG("%s", hdev->name);
3223
3224 hci_dev_lock(hdev);
3225
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003226 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003227 goto unlock;
3228
Szymon Janc2763eda2011-03-22 13:12:22 +01003229 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3230 if (data) {
3231 struct hci_cp_remote_oob_data_reply cp;
3232
3233 bacpy(&cp.bdaddr, &ev->bdaddr);
3234 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3235 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3236
3237 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
3238 &cp);
3239 } else {
3240 struct hci_cp_remote_oob_data_neg_reply cp;
3241
3242 bacpy(&cp.bdaddr, &ev->bdaddr);
3243 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
3244 &cp);
3245 }
3246
Szymon Jance1ba1f12011-04-06 13:01:59 +02003247unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003248 hci_dev_unlock(hdev);
3249}
3250
Ville Tervofcd89c02011-02-10 22:38:47 -03003251static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3252{
3253 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3254 struct hci_conn *conn;
3255
3256 BT_DBG("%s status %d", hdev->name, ev->status);
3257
3258 hci_dev_lock(hdev);
3259
3260 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03003261 if (!conn) {
3262 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3263 if (!conn) {
3264 BT_ERR("No memory for new connection");
3265 hci_dev_unlock(hdev);
3266 return;
3267 }
Andre Guedes29b79882011-05-31 14:20:54 -03003268
3269 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03003270 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003271
3272 if (ev->status) {
Johan Hedberg48264f02011-11-09 13:58:58 +02003273 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3274 conn->dst_type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003275 hci_proto_connect_cfm(conn, ev->status);
3276 conn->state = BT_CLOSED;
3277 hci_conn_del(conn);
3278 goto unlock;
3279 }
3280
Johan Hedbergb644ba32012-01-17 21:48:47 +02003281 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3282 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
3283 conn->dst_type, NULL, 0, 0);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003284
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003285 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003286 conn->handle = __le16_to_cpu(ev->handle);
3287 conn->state = BT_CONNECTED;
3288
3289 hci_conn_hold_device(conn);
3290 hci_conn_add_sysfs(conn);
3291
3292 hci_proto_connect_cfm(conn, ev->status);
3293
3294unlock:
3295 hci_dev_unlock(hdev);
3296}
3297
Andre Guedes9aa04c92011-05-26 16:23:51 -03003298static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3299 struct sk_buff *skb)
3300{
Andre Guedese95beb42011-09-26 20:48:35 -03003301 u8 num_reports = skb->data[0];
3302 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003303 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003304
3305 hci_dev_lock(hdev);
3306
Andre Guedese95beb42011-09-26 20:48:35 -03003307 while (num_reports--) {
3308 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003309
Andre Guedes9aa04c92011-05-26 16:23:51 -03003310 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03003311
Andre Guedes3c9e9192012-01-10 18:20:50 -03003312 rssi = ev->data[ev->length];
3313 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003314 NULL, rssi, 0, 1, ev->data,
3315 ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003316
Andre Guedese95beb42011-09-26 20:48:35 -03003317 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003318 }
3319
3320 hci_dev_unlock(hdev);
3321}
3322
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003323static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
3324 struct sk_buff *skb)
3325{
3326 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3327 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003328 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003329 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003330 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003331
3332 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3333
3334 hci_dev_lock(hdev);
3335
3336 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003337 if (conn == NULL)
3338 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003339
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003340 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3341 if (ltk == NULL)
3342 goto not_found;
3343
3344 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003345 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003346
3347 if (ltk->authenticated)
3348 conn->sec_level = BT_SECURITY_HIGH;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003349
3350 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3351
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003352 if (ltk->type & HCI_SMP_STK) {
3353 list_del(&ltk->list);
3354 kfree(ltk);
3355 }
3356
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003357 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003358
3359 return;
3360
3361not_found:
3362 neg.handle = ev->handle;
3363 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3364 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003365}
3366
Ville Tervofcd89c02011-02-10 22:38:47 -03003367static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3368{
3369 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3370
3371 skb_pull(skb, sizeof(*le_ev));
3372
3373 switch (le_ev->subevent) {
3374 case HCI_EV_LE_CONN_COMPLETE:
3375 hci_le_conn_complete_evt(hdev, skb);
3376 break;
3377
Andre Guedes9aa04c92011-05-26 16:23:51 -03003378 case HCI_EV_LE_ADVERTISING_REPORT:
3379 hci_le_adv_report_evt(hdev, skb);
3380 break;
3381
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003382 case HCI_EV_LE_LTK_REQ:
3383 hci_le_ltk_request_evt(hdev, skb);
3384 break;
3385
Ville Tervofcd89c02011-02-10 22:38:47 -03003386 default:
3387 break;
3388 }
3389}
3390
Linus Torvalds1da177e2005-04-16 15:20:36 -07003391void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3392{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003393 struct hci_event_hdr *hdr = (void *) skb->data;
3394 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003395
3396 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3397
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003398 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003399 case HCI_EV_INQUIRY_COMPLETE:
3400 hci_inquiry_complete_evt(hdev, skb);
3401 break;
3402
3403 case HCI_EV_INQUIRY_RESULT:
3404 hci_inquiry_result_evt(hdev, skb);
3405 break;
3406
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003407 case HCI_EV_CONN_COMPLETE:
3408 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003409 break;
3410
Linus Torvalds1da177e2005-04-16 15:20:36 -07003411 case HCI_EV_CONN_REQUEST:
3412 hci_conn_request_evt(hdev, skb);
3413 break;
3414
Linus Torvalds1da177e2005-04-16 15:20:36 -07003415 case HCI_EV_DISCONN_COMPLETE:
3416 hci_disconn_complete_evt(hdev, skb);
3417 break;
3418
Linus Torvalds1da177e2005-04-16 15:20:36 -07003419 case HCI_EV_AUTH_COMPLETE:
3420 hci_auth_complete_evt(hdev, skb);
3421 break;
3422
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003423 case HCI_EV_REMOTE_NAME:
3424 hci_remote_name_evt(hdev, skb);
3425 break;
3426
Linus Torvalds1da177e2005-04-16 15:20:36 -07003427 case HCI_EV_ENCRYPT_CHANGE:
3428 hci_encrypt_change_evt(hdev, skb);
3429 break;
3430
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003431 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3432 hci_change_link_key_complete_evt(hdev, skb);
3433 break;
3434
3435 case HCI_EV_REMOTE_FEATURES:
3436 hci_remote_features_evt(hdev, skb);
3437 break;
3438
3439 case HCI_EV_REMOTE_VERSION:
3440 hci_remote_version_evt(hdev, skb);
3441 break;
3442
3443 case HCI_EV_QOS_SETUP_COMPLETE:
3444 hci_qos_setup_complete_evt(hdev, skb);
3445 break;
3446
3447 case HCI_EV_CMD_COMPLETE:
3448 hci_cmd_complete_evt(hdev, skb);
3449 break;
3450
3451 case HCI_EV_CMD_STATUS:
3452 hci_cmd_status_evt(hdev, skb);
3453 break;
3454
3455 case HCI_EV_ROLE_CHANGE:
3456 hci_role_change_evt(hdev, skb);
3457 break;
3458
3459 case HCI_EV_NUM_COMP_PKTS:
3460 hci_num_comp_pkts_evt(hdev, skb);
3461 break;
3462
3463 case HCI_EV_MODE_CHANGE:
3464 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003465 break;
3466
3467 case HCI_EV_PIN_CODE_REQ:
3468 hci_pin_code_request_evt(hdev, skb);
3469 break;
3470
3471 case HCI_EV_LINK_KEY_REQ:
3472 hci_link_key_request_evt(hdev, skb);
3473 break;
3474
3475 case HCI_EV_LINK_KEY_NOTIFY:
3476 hci_link_key_notify_evt(hdev, skb);
3477 break;
3478
3479 case HCI_EV_CLOCK_OFFSET:
3480 hci_clock_offset_evt(hdev, skb);
3481 break;
3482
Marcel Holtmanna8746412008-07-14 20:13:46 +02003483 case HCI_EV_PKT_TYPE_CHANGE:
3484 hci_pkt_type_change_evt(hdev, skb);
3485 break;
3486
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003487 case HCI_EV_PSCAN_REP_MODE:
3488 hci_pscan_rep_mode_evt(hdev, skb);
3489 break;
3490
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003491 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3492 hci_inquiry_result_with_rssi_evt(hdev, skb);
3493 break;
3494
3495 case HCI_EV_REMOTE_EXT_FEATURES:
3496 hci_remote_ext_features_evt(hdev, skb);
3497 break;
3498
3499 case HCI_EV_SYNC_CONN_COMPLETE:
3500 hci_sync_conn_complete_evt(hdev, skb);
3501 break;
3502
3503 case HCI_EV_SYNC_CONN_CHANGED:
3504 hci_sync_conn_changed_evt(hdev, skb);
3505 break;
3506
Marcel Holtmann04837f62006-07-03 10:02:33 +02003507 case HCI_EV_SNIFF_SUBRATE:
3508 hci_sniff_subrate_evt(hdev, skb);
3509 break;
3510
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003511 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3512 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003513 break;
3514
Marcel Holtmann04936842008-07-14 20:13:48 +02003515 case HCI_EV_IO_CAPA_REQUEST:
3516 hci_io_capa_request_evt(hdev, skb);
3517 break;
3518
Johan Hedberg03b555e2011-01-04 15:40:05 +02003519 case HCI_EV_IO_CAPA_REPLY:
3520 hci_io_capa_reply_evt(hdev, skb);
3521 break;
3522
Johan Hedberga5c29682011-02-19 12:05:57 -03003523 case HCI_EV_USER_CONFIRM_REQUEST:
3524 hci_user_confirm_request_evt(hdev, skb);
3525 break;
3526
Brian Gix1143d452011-11-23 08:28:34 -08003527 case HCI_EV_USER_PASSKEY_REQUEST:
3528 hci_user_passkey_request_evt(hdev, skb);
3529 break;
3530
Marcel Holtmann04936842008-07-14 20:13:48 +02003531 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3532 hci_simple_pair_complete_evt(hdev, skb);
3533 break;
3534
Marcel Holtmann41a96212008-07-14 20:13:48 +02003535 case HCI_EV_REMOTE_HOST_FEATURES:
3536 hci_remote_host_features_evt(hdev, skb);
3537 break;
3538
Ville Tervofcd89c02011-02-10 22:38:47 -03003539 case HCI_EV_LE_META:
3540 hci_le_meta_evt(hdev, skb);
3541 break;
3542
Szymon Janc2763eda2011-03-22 13:12:22 +01003543 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3544 hci_remote_oob_data_request_evt(hdev, skb);
3545 break;
3546
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003547 case HCI_EV_NUM_COMP_BLOCKS:
3548 hci_num_comp_blocks_evt(hdev, skb);
3549 break;
3550
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003551 default:
3552 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003553 break;
3554 }
3555
3556 kfree_skb(skb);
3557 hdev->stat.evt_rx++;
3558}