blob: 49b387cdcc3835bfe06da1583ec60ab295b809fa [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>
38#include <linux/notifier.h>
39#include <net/sock.h>
40
41#include <asm/system.h>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020042#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <asm/unaligned.h>
44
45#include <net/bluetooth/bluetooth.h>
46#include <net/bluetooth/hci_core.h>
47
Linus Torvalds1da177e2005-04-16 15:20:36 -070048/* Handle HCI Event packets */
49
Marcel Holtmanna9de9242007-10-20 13:33:56 +020050static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070051{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020052 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
Marcel Holtmanna9de9242007-10-20 13:33:56 +020054 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
Marcel Holtmanna9de9242007-10-20 13:33:56 +020056 if (status)
57 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
Marcel Holtmanna9de9242007-10-20 13:33:56 +020059 clear_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010060
Johan Hedberg23bb5762010-12-21 23:01:27 +020061 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010062
Marcel Holtmanna9de9242007-10-20 13:33:56 +020063 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070064}
65
Marcel Holtmanna9de9242007-10-20 13:33:56 +020066static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020068 __u8 status = *((__u8 *) skb->data);
69
70 BT_DBG("%s status 0x%x", hdev->name, status);
71
72 if (status)
73 return;
74
75 clear_bit(HCI_INQUIRY, &hdev->flags);
76
77 hci_conn_check_pending(hdev);
78}
79
80static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
81{
82 BT_DBG("%s", hdev->name);
83}
84
85static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
86{
87 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
Marcel Holtmanna9de9242007-10-20 13:33:56 +020090 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
Marcel Holtmanna9de9242007-10-20 13:33:56 +020092 if (rp->status)
93 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
Marcel Holtmanna9de9242007-10-20 13:33:56 +020095 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Marcel Holtmanna9de9242007-10-20 13:33:56 +020097 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
98 if (conn) {
99 if (rp->role)
100 conn->link_mode &= ~HCI_LM_MASTER;
101 else
102 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200104
105 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106}
107
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200108static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
109{
110 struct hci_rp_read_link_policy *rp = (void *) skb->data;
111 struct hci_conn *conn;
112
113 BT_DBG("%s status 0x%x", hdev->name, rp->status);
114
115 if (rp->status)
116 return;
117
118 hci_dev_lock(hdev);
119
120 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
121 if (conn)
122 conn->link_policy = __le16_to_cpu(rp->policy);
123
124 hci_dev_unlock(hdev);
125}
126
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200127static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200129 struct hci_rp_write_link_policy *rp = (void *) skb->data;
130 struct hci_conn *conn;
131 void *sent;
132
133 BT_DBG("%s status 0x%x", hdev->name, rp->status);
134
135 if (rp->status)
136 return;
137
138 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
139 if (!sent)
140 return;
141
142 hci_dev_lock(hdev);
143
144 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200145 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700146 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200147
148 hci_dev_unlock(hdev);
149}
150
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200151static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
152{
153 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
154
155 BT_DBG("%s status 0x%x", hdev->name, rp->status);
156
157 if (rp->status)
158 return;
159
160 hdev->link_policy = __le16_to_cpu(rp->policy);
161}
162
163static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
164{
165 __u8 status = *((__u8 *) skb->data);
166 void *sent;
167
168 BT_DBG("%s status 0x%x", hdev->name, status);
169
170 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
171 if (!sent)
172 return;
173
174 if (!status)
175 hdev->link_policy = get_unaligned_le16(sent);
176
Johan Hedberg23bb5762010-12-21 23:01:27 +0200177 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200178}
179
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200180static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
181{
182 __u8 status = *((__u8 *) skb->data);
183
184 BT_DBG("%s status 0x%x", hdev->name, status);
185
Johan Hedberg23bb5762010-12-21 23:01:27 +0200186 hci_req_complete(hdev, HCI_OP_RESET, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200187}
188
189static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
190{
191 __u8 status = *((__u8 *) skb->data);
192 void *sent;
193
194 BT_DBG("%s status 0x%x", hdev->name, status);
195
Marcel Holtmannf383f272008-07-14 20:13:47 +0200196 if (status)
197 return;
198
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200199 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
200 if (!sent)
201 return;
202
Marcel Holtmannf383f272008-07-14 20:13:47 +0200203 memcpy(hdev->dev_name, sent, 248);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200204}
205
206static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
207{
208 struct hci_rp_read_local_name *rp = (void *) skb->data;
209
210 BT_DBG("%s status 0x%x", hdev->name, rp->status);
211
212 if (rp->status)
213 return;
214
215 memcpy(hdev->dev_name, rp->name, 248);
216}
217
218static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
219{
220 __u8 status = *((__u8 *) skb->data);
221 void *sent;
222
223 BT_DBG("%s status 0x%x", hdev->name, status);
224
225 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
226 if (!sent)
227 return;
228
229 if (!status) {
230 __u8 param = *((__u8 *) sent);
231
232 if (param == AUTH_ENABLED)
233 set_bit(HCI_AUTH, &hdev->flags);
234 else
235 clear_bit(HCI_AUTH, &hdev->flags);
236 }
237
Johan Hedberg23bb5762010-12-21 23:01:27 +0200238 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200239}
240
241static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
242{
243 __u8 status = *((__u8 *) skb->data);
244 void *sent;
245
246 BT_DBG("%s status 0x%x", hdev->name, status);
247
248 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
249 if (!sent)
250 return;
251
252 if (!status) {
253 __u8 param = *((__u8 *) sent);
254
255 if (param)
256 set_bit(HCI_ENCRYPT, &hdev->flags);
257 else
258 clear_bit(HCI_ENCRYPT, &hdev->flags);
259 }
260
Johan Hedberg23bb5762010-12-21 23:01:27 +0200261 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200262}
263
264static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
265{
266 __u8 status = *((__u8 *) skb->data);
267 void *sent;
268
269 BT_DBG("%s status 0x%x", hdev->name, status);
270
271 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
272 if (!sent)
273 return;
274
275 if (!status) {
276 __u8 param = *((__u8 *) sent);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200277 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200278
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200279 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
280 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200281
Johan Hedberg73f22f62010-12-29 16:00:25 +0200282 if (param & SCAN_INQUIRY) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200283 set_bit(HCI_ISCAN, &hdev->flags);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200284 if (!old_iscan)
285 mgmt_discoverable(hdev->id, 1);
286 } else if (old_iscan)
Johan Hedberg73f22f62010-12-29 16:00:25 +0200287 mgmt_discoverable(hdev->id, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200288
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200289 if (param & SCAN_PAGE) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200290 set_bit(HCI_PSCAN, &hdev->flags);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200291 if (!old_pscan)
292 mgmt_connectable(hdev->id, 1);
293 } else if (old_pscan)
294 mgmt_connectable(hdev->id, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200295 }
296
Johan Hedberg23bb5762010-12-21 23:01:27 +0200297 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200298}
299
300static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
301{
302 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
303
304 BT_DBG("%s status 0x%x", hdev->name, rp->status);
305
306 if (rp->status)
307 return;
308
309 memcpy(hdev->dev_class, rp->dev_class, 3);
310
311 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
312 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
313}
314
315static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
316{
317 __u8 status = *((__u8 *) skb->data);
318 void *sent;
319
320 BT_DBG("%s status 0x%x", hdev->name, status);
321
Marcel Holtmannf383f272008-07-14 20:13:47 +0200322 if (status)
323 return;
324
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200325 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
326 if (!sent)
327 return;
328
Marcel Holtmannf383f272008-07-14 20:13:47 +0200329 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200330}
331
332static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
333{
334 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200336
337 BT_DBG("%s status 0x%x", hdev->name, rp->status);
338
339 if (rp->status)
340 return;
341
342 setting = __le16_to_cpu(rp->voice_setting);
343
Marcel Holtmannf383f272008-07-14 20:13:47 +0200344 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200345 return;
346
347 hdev->voice_setting = setting;
348
349 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
350
351 if (hdev->notify) {
352 tasklet_disable(&hdev->tx_task);
353 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
354 tasklet_enable(&hdev->tx_task);
355 }
356}
357
358static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
359{
360 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200361 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362 void *sent;
363
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200364 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365
Marcel Holtmannf383f272008-07-14 20:13:47 +0200366 if (status)
367 return;
368
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200369 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
370 if (!sent)
371 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372
Marcel Holtmannf383f272008-07-14 20:13:47 +0200373 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374
Marcel Holtmannf383f272008-07-14 20:13:47 +0200375 if (hdev->voice_setting == setting)
376 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377
Marcel Holtmannf383f272008-07-14 20:13:47 +0200378 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379
Marcel Holtmannf383f272008-07-14 20:13:47 +0200380 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
381
382 if (hdev->notify) {
383 tasklet_disable(&hdev->tx_task);
384 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
385 tasklet_enable(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 }
387}
388
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200391 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200393 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394
Johan Hedberg23bb5762010-12-21 23:01:27 +0200395 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396}
397
Marcel Holtmann333140b2008-07-14 20:13:48 +0200398static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
399{
400 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
401
402 BT_DBG("%s status 0x%x", hdev->name, rp->status);
403
404 if (rp->status)
405 return;
406
407 hdev->ssp_mode = rp->mode;
408}
409
410static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
411{
412 __u8 status = *((__u8 *) skb->data);
413 void *sent;
414
415 BT_DBG("%s status 0x%x", hdev->name, status);
416
417 if (status)
418 return;
419
420 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
421 if (!sent)
422 return;
423
424 hdev->ssp_mode = *((__u8 *) sent);
425}
426
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200427static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
428{
429 struct hci_rp_read_local_version *rp = (void *) skb->data;
430
431 BT_DBG("%s status 0x%x", hdev->name, rp->status);
432
433 if (rp->status)
434 return;
435
436 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200437 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
438 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200439
440 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
441 hdev->manufacturer,
442 hdev->hci_ver, hdev->hci_rev);
443}
444
445static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
446{
447 struct hci_rp_read_local_commands *rp = (void *) skb->data;
448
449 BT_DBG("%s status 0x%x", hdev->name, rp->status);
450
451 if (rp->status)
452 return;
453
454 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
455}
456
457static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
458{
459 struct hci_rp_read_local_features *rp = (void *) skb->data;
460
461 BT_DBG("%s status 0x%x", hdev->name, rp->status);
462
463 if (rp->status)
464 return;
465
466 memcpy(hdev->features, rp->features, 8);
467
468 /* Adjust default settings according to features
469 * supported by device. */
470
471 if (hdev->features[0] & LMP_3SLOT)
472 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
473
474 if (hdev->features[0] & LMP_5SLOT)
475 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
476
477 if (hdev->features[1] & LMP_HV2) {
478 hdev->pkt_type |= (HCI_HV2);
479 hdev->esco_type |= (ESCO_HV2);
480 }
481
482 if (hdev->features[1] & LMP_HV3) {
483 hdev->pkt_type |= (HCI_HV3);
484 hdev->esco_type |= (ESCO_HV3);
485 }
486
487 if (hdev->features[3] & LMP_ESCO)
488 hdev->esco_type |= (ESCO_EV3);
489
490 if (hdev->features[4] & LMP_EV4)
491 hdev->esco_type |= (ESCO_EV4);
492
493 if (hdev->features[4] & LMP_EV5)
494 hdev->esco_type |= (ESCO_EV5);
495
Marcel Holtmannefc76882009-02-06 09:13:37 +0100496 if (hdev->features[5] & LMP_EDR_ESCO_2M)
497 hdev->esco_type |= (ESCO_2EV3);
498
499 if (hdev->features[5] & LMP_EDR_ESCO_3M)
500 hdev->esco_type |= (ESCO_3EV3);
501
502 if (hdev->features[5] & LMP_EDR_3S_ESCO)
503 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
504
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200505 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
506 hdev->features[0], hdev->features[1],
507 hdev->features[2], hdev->features[3],
508 hdev->features[4], hdev->features[5],
509 hdev->features[6], hdev->features[7]);
510}
511
512static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
513{
514 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
515
516 BT_DBG("%s status 0x%x", hdev->name, rp->status);
517
518 if (rp->status)
519 return;
520
521 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
522 hdev->sco_mtu = rp->sco_mtu;
523 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
524 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
525
526 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
527 hdev->sco_mtu = 64;
528 hdev->sco_pkts = 8;
529 }
530
531 hdev->acl_cnt = hdev->acl_pkts;
532 hdev->sco_cnt = hdev->sco_pkts;
533
534 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
535 hdev->acl_mtu, hdev->acl_pkts,
536 hdev->sco_mtu, hdev->sco_pkts);
537}
538
539static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
540{
541 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
542
543 BT_DBG("%s status 0x%x", hdev->name, rp->status);
544
545 if (!rp->status)
546 bacpy(&hdev->bdaddr, &rp->bdaddr);
547
Johan Hedberg23bb5762010-12-21 23:01:27 +0200548 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
549}
550
551static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
552{
553 __u8 status = *((__u8 *) skb->data);
554
555 BT_DBG("%s status 0x%x", hdev->name, status);
556
557 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200558}
559
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200560static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
561 struct sk_buff *skb)
562{
563 __u8 status = *((__u8 *) skb->data);
564
565 BT_DBG("%s status 0x%x", hdev->name, status);
566
567 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
568}
569
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200570static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
571{
572 BT_DBG("%s status 0x%x", hdev->name, status);
573
574 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +0200575 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200576
577 hci_conn_check_pending(hdev);
578 } else
579 set_bit(HCI_INQUIRY, &hdev->flags);
580}
581
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
583{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200584 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200587 BT_DBG("%s status 0x%x", hdev->name, status);
588
589 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 if (!cp)
591 return;
592
593 hci_dev_lock(hdev);
594
595 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
596
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200597 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598
599 if (status) {
600 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200601 if (status != 0x0c || conn->attempt > 2) {
602 conn->state = BT_CLOSED;
603 hci_proto_connect_cfm(conn, status);
604 hci_conn_del(conn);
605 } else
606 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 }
608 } else {
609 if (!conn) {
610 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
611 if (conn) {
612 conn->out = 1;
613 conn->link_mode |= HCI_LM_MASTER;
614 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -0300615 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 }
617 }
618
619 hci_dev_unlock(hdev);
620}
621
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200622static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200624 struct hci_cp_add_sco *cp;
625 struct hci_conn *acl, *sco;
626 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200628 BT_DBG("%s status 0x%x", hdev->name, status);
629
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200630 if (!status)
631 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200633 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
634 if (!cp)
635 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200637 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200639 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100640
641 hci_dev_lock(hdev);
642
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200643 acl = hci_conn_hash_lookup_handle(hdev, handle);
644 if (acl && (sco = acl->link)) {
645 sco->state = BT_CLOSED;
646
647 hci_proto_connect_cfm(sco, status);
648 hci_conn_del(sco);
649 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100650
651 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652}
653
Marcel Holtmannf8558552008-07-14 20:13:49 +0200654static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
655{
656 struct hci_cp_auth_requested *cp;
657 struct hci_conn *conn;
658
659 BT_DBG("%s status 0x%x", hdev->name, status);
660
661 if (!status)
662 return;
663
664 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
665 if (!cp)
666 return;
667
668 hci_dev_lock(hdev);
669
670 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
671 if (conn) {
672 if (conn->state == BT_CONFIG) {
673 hci_proto_connect_cfm(conn, status);
674 hci_conn_put(conn);
675 }
676 }
677
678 hci_dev_unlock(hdev);
679}
680
681static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
682{
683 struct hci_cp_set_conn_encrypt *cp;
684 struct hci_conn *conn;
685
686 BT_DBG("%s status 0x%x", hdev->name, status);
687
688 if (!status)
689 return;
690
691 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
692 if (!cp)
693 return;
694
695 hci_dev_lock(hdev);
696
697 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
698 if (conn) {
699 if (conn->state == BT_CONFIG) {
700 hci_proto_connect_cfm(conn, status);
701 hci_conn_put(conn);
702 }
703 }
704
705 hci_dev_unlock(hdev);
706}
707
Johan Hedberg127178d2010-11-18 22:22:29 +0200708static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Johan Hedberg392599b2010-11-18 22:22:28 +0200709 struct hci_conn *conn)
710{
Johan Hedberg392599b2010-11-18 22:22:28 +0200711 if (conn->state != BT_CONFIG || !conn->out)
712 return 0;
713
Johan Hedberg765c2a92011-01-19 12:06:52 +0530714 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +0200715 return 0;
716
717 /* Only request authentication for SSP connections or non-SSP
718 * devices with sec_level HIGH */
719 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
Johan Hedberg765c2a92011-01-19 12:06:52 +0530720 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +0200721 return 0;
722
Johan Hedberg392599b2010-11-18 22:22:28 +0200723 return 1;
724}
725
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200726static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
727{
Johan Hedberg127178d2010-11-18 22:22:29 +0200728 struct hci_cp_remote_name_req *cp;
729 struct hci_conn *conn;
730
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200731 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +0200732
733 /* If successful wait for the name req complete event before
734 * checking for the need to do authentication */
735 if (!status)
736 return;
737
738 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
739 if (!cp)
740 return;
741
742 hci_dev_lock(hdev);
743
744 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
745 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
746 struct hci_cp_auth_requested cp;
747 cp.handle = __cpu_to_le16(conn->handle);
748 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
749 }
750
751 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200752}
753
Marcel Holtmann769be972008-07-14 20:13:49 +0200754static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
755{
756 struct hci_cp_read_remote_features *cp;
757 struct hci_conn *conn;
758
759 BT_DBG("%s status 0x%x", hdev->name, status);
760
761 if (!status)
762 return;
763
764 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
765 if (!cp)
766 return;
767
768 hci_dev_lock(hdev);
769
770 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
771 if (conn) {
772 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +0200773 hci_proto_connect_cfm(conn, status);
774 hci_conn_put(conn);
775 }
776 }
777
778 hci_dev_unlock(hdev);
779}
780
781static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
782{
783 struct hci_cp_read_remote_ext_features *cp;
784 struct hci_conn *conn;
785
786 BT_DBG("%s status 0x%x", hdev->name, status);
787
788 if (!status)
789 return;
790
791 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
792 if (!cp)
793 return;
794
795 hci_dev_lock(hdev);
796
797 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
798 if (conn) {
799 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +0200800 hci_proto_connect_cfm(conn, status);
801 hci_conn_put(conn);
802 }
803 }
804
805 hci_dev_unlock(hdev);
806}
807
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200808static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
809{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200810 struct hci_cp_setup_sync_conn *cp;
811 struct hci_conn *acl, *sco;
812 __u16 handle;
813
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200814 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200815
816 if (!status)
817 return;
818
819 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
820 if (!cp)
821 return;
822
823 handle = __le16_to_cpu(cp->handle);
824
825 BT_DBG("%s handle %d", hdev->name, handle);
826
827 hci_dev_lock(hdev);
828
829 acl = hci_conn_hash_lookup_handle(hdev, handle);
830 if (acl && (sco = acl->link)) {
831 sco->state = BT_CLOSED;
832
833 hci_proto_connect_cfm(sco, status);
834 hci_conn_del(sco);
835 }
836
837 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200838}
839
840static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
841{
842 struct hci_cp_sniff_mode *cp;
843 struct hci_conn *conn;
844
845 BT_DBG("%s status 0x%x", hdev->name, status);
846
847 if (!status)
848 return;
849
850 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
851 if (!cp)
852 return;
853
854 hci_dev_lock(hdev);
855
856 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400857 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200858 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
859
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400860 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
861 hci_sco_setup(conn, status);
862 }
863
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200864 hci_dev_unlock(hdev);
865}
866
867static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
868{
869 struct hci_cp_exit_sniff_mode *cp;
870 struct hci_conn *conn;
871
872 BT_DBG("%s status 0x%x", hdev->name, status);
873
874 if (!status)
875 return;
876
877 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
878 if (!cp)
879 return;
880
881 hci_dev_lock(hdev);
882
883 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400884 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200885 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
886
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400887 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
888 hci_sco_setup(conn, status);
889 }
890
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200891 hci_dev_unlock(hdev);
892}
893
894static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
895{
896 __u8 status = *((__u8 *) skb->data);
897
898 BT_DBG("%s status %d", hdev->name, status);
899
900 clear_bit(HCI_INQUIRY, &hdev->flags);
901
Johan Hedberg23bb5762010-12-21 23:01:27 +0200902 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200903
904 hci_conn_check_pending(hdev);
905}
906
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
908{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700909 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200910 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911 int num_rsp = *((__u8 *) skb->data);
912
913 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
914
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700915 if (!num_rsp)
916 return;
917
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700919
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 for (; num_rsp; num_rsp--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921 bacpy(&data.bdaddr, &info->bdaddr);
922 data.pscan_rep_mode = info->pscan_rep_mode;
923 data.pscan_period_mode = info->pscan_period_mode;
924 data.pscan_mode = info->pscan_mode;
925 memcpy(data.dev_class, info->dev_class, 3);
926 data.clock_offset = info->clock_offset;
927 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +0200928 data.ssp_mode = 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 info++;
930 hci_inquiry_cache_update(hdev, &data);
931 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700932
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933 hci_dev_unlock(hdev);
934}
935
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200936static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200938 struct hci_ev_conn_complete *ev = (void *) skb->data;
939 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200941 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700942
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700944
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200945 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +0200946 if (!conn) {
947 if (ev->link_type != SCO_LINK)
948 goto unlock;
949
950 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
951 if (!conn)
952 goto unlock;
953
954 conn->type = SCO_LINK;
955 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700956
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200957 if (!ev->status) {
958 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +0200959
960 if (conn->type == ACL_LINK) {
961 conn->state = BT_CONFIG;
962 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +0200963 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +0200964 } else
965 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200966
Marcel Holtmann9eba32b2009-08-22 14:19:26 -0700967 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +0200968 hci_conn_add_sysfs(conn);
969
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200970 if (test_bit(HCI_AUTH, &hdev->flags))
971 conn->link_mode |= HCI_LM_AUTH;
972
973 if (test_bit(HCI_ENCRYPT, &hdev->flags))
974 conn->link_mode |= HCI_LM_ENCRYPT;
975
976 /* Get remote features */
977 if (conn->type == ACL_LINK) {
978 struct hci_cp_read_remote_features cp;
979 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +0200980 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
981 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700982 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700983
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200984 /* Set packet type for incoming connection */
Marcel Holtmanna8746412008-07-14 20:13:46 +0200985 if (!conn->out && hdev->hci_ver < 3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200986 struct hci_cp_change_conn_ptype cp;
987 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +0200988 cp.pkt_type = cpu_to_le16(conn->pkt_type);
989 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
990 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200991 }
992 } else
993 conn->state = BT_CLOSED;
994
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400995 if (conn->type == ACL_LINK)
996 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700997
Marcel Holtmann769be972008-07-14 20:13:49 +0200998 if (ev->status) {
999 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001000 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001001 } else if (ev->link_type != ACL_LINK)
1002 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001003
1004unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001006
1007 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008}
1009
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1011{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001012 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 int mask = hdev->link_mode;
1014
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001015 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1016 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017
1018 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1019
Johan Hedbergf0358562010-05-18 13:20:32 +02001020 if ((mask & HCI_LM_ACCEPT) && !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001022 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024
1025 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001026
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001027 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1028 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001029 memcpy(ie->data.dev_class, ev->dev_class, 3);
1030
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1032 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001033 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1034 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001035 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 hci_dev_unlock(hdev);
1037 return;
1038 }
1039 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001040
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 memcpy(conn->dev_class, ev->dev_class, 3);
1042 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001043
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 hci_dev_unlock(hdev);
1045
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001046 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1047 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001049 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001051 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1052 cp.role = 0x00; /* Become master */
1053 else
1054 cp.role = 0x01; /* Remain slave */
1055
1056 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1057 sizeof(cp), &cp);
1058 } else {
1059 struct hci_cp_accept_sync_conn_req cp;
1060
1061 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001062 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001063
1064 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1065 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1066 cp.max_latency = cpu_to_le16(0xffff);
1067 cp.content_format = cpu_to_le16(hdev->voice_setting);
1068 cp.retrans_effort = 0xff;
1069
1070 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1071 sizeof(cp), &cp);
1072 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 } else {
1074 /* Connection rejected */
1075 struct hci_cp_reject_conn_req cp;
1076
1077 bacpy(&cp.bdaddr, &ev->bdaddr);
1078 cp.reason = 0x0f;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001079 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 }
1081}
1082
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1084{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001085 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001086 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087
1088 BT_DBG("%s status %d", hdev->name, ev->status);
1089
1090 if (ev->status)
1091 return;
1092
1093 hci_dev_lock(hdev);
1094
Marcel Holtmann04837f62006-07-03 10:02:33 +02001095 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 if (conn) {
1097 conn->state = BT_CLOSED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001098
Marcel Holtmann2950f212009-02-12 14:02:50 +01001099 hci_proto_disconn_cfm(conn, ev->reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 hci_conn_del(conn);
1101 }
1102
1103 hci_dev_unlock(hdev);
1104}
1105
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001106static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1107{
1108 struct hci_ev_auth_complete *ev = (void *) skb->data;
1109 struct hci_conn *conn;
1110
1111 BT_DBG("%s status %d", hdev->name, ev->status);
1112
1113 hci_dev_lock(hdev);
1114
1115 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1116 if (conn) {
Johan Hedberg765c2a92011-01-19 12:06:52 +05301117 if (!ev->status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001118 conn->link_mode |= HCI_LM_AUTH;
Johan Hedberg765c2a92011-01-19 12:06:52 +05301119 conn->sec_level = conn->pending_sec_level;
1120 } else
Johan Hedbergda213f42010-06-18 11:08:56 +03001121 conn->sec_level = BT_SECURITY_LOW;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001122
1123 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1124
Marcel Holtmannf8558552008-07-14 20:13:49 +02001125 if (conn->state == BT_CONFIG) {
1126 if (!ev->status && hdev->ssp_mode > 0 &&
1127 conn->ssp_mode > 0) {
1128 struct hci_cp_set_conn_encrypt cp;
1129 cp.handle = ev->handle;
1130 cp.encrypt = 0x01;
1131 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1132 sizeof(cp), &cp);
1133 } else {
1134 conn->state = BT_CONNECTED;
1135 hci_proto_connect_cfm(conn, ev->status);
1136 hci_conn_put(conn);
1137 }
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001138 } else {
Marcel Holtmannf8558552008-07-14 20:13:49 +02001139 hci_auth_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001140
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001141 hci_conn_hold(conn);
1142 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1143 hci_conn_put(conn);
1144 }
1145
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001146 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1147 if (!ev->status) {
1148 struct hci_cp_set_conn_encrypt cp;
Marcel Holtmannf8558552008-07-14 20:13:49 +02001149 cp.handle = ev->handle;
1150 cp.encrypt = 0x01;
1151 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1152 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001153 } else {
1154 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1155 hci_encrypt_cfm(conn, ev->status, 0x00);
1156 }
1157 }
1158 }
1159
1160 hci_dev_unlock(hdev);
1161}
1162
1163static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1164{
Johan Hedberg127178d2010-11-18 22:22:29 +02001165 struct hci_ev_remote_name *ev = (void *) skb->data;
1166 struct hci_conn *conn;
1167
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001168 BT_DBG("%s", hdev->name);
1169
1170 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001171
1172 hci_dev_lock(hdev);
1173
1174 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1175 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
1176 struct hci_cp_auth_requested cp;
1177 cp.handle = __cpu_to_le16(conn->handle);
1178 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1179 }
1180
1181 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001182}
1183
1184static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1185{
1186 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1187 struct hci_conn *conn;
1188
1189 BT_DBG("%s status %d", hdev->name, ev->status);
1190
1191 hci_dev_lock(hdev);
1192
1193 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1194 if (conn) {
1195 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001196 if (ev->encrypt) {
1197 /* Encryption implies authentication */
1198 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001199 conn->link_mode |= HCI_LM_ENCRYPT;
Marcel Holtmannae293192008-07-14 20:13:45 +02001200 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001201 conn->link_mode &= ~HCI_LM_ENCRYPT;
1202 }
1203
1204 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1205
Marcel Holtmannf8558552008-07-14 20:13:49 +02001206 if (conn->state == BT_CONFIG) {
1207 if (!ev->status)
1208 conn->state = BT_CONNECTED;
1209
1210 hci_proto_connect_cfm(conn, ev->status);
1211 hci_conn_put(conn);
1212 } else
1213 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001214 }
1215
1216 hci_dev_unlock(hdev);
1217}
1218
1219static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1220{
1221 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1222 struct hci_conn *conn;
1223
1224 BT_DBG("%s status %d", hdev->name, ev->status);
1225
1226 hci_dev_lock(hdev);
1227
1228 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1229 if (conn) {
1230 if (!ev->status)
1231 conn->link_mode |= HCI_LM_SECURE;
1232
1233 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1234
1235 hci_key_change_cfm(conn, ev->status);
1236 }
1237
1238 hci_dev_unlock(hdev);
1239}
1240
1241static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1242{
1243 struct hci_ev_remote_features *ev = (void *) skb->data;
1244 struct hci_conn *conn;
1245
1246 BT_DBG("%s status %d", hdev->name, ev->status);
1247
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001248 hci_dev_lock(hdev);
1249
1250 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001251 if (!conn)
1252 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001253
Johan Hedbergccd556f2010-11-10 17:11:51 +02001254 if (!ev->status)
1255 memcpy(conn->features, ev->features, 8);
1256
1257 if (conn->state != BT_CONFIG)
1258 goto unlock;
1259
1260 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1261 struct hci_cp_read_remote_ext_features cp;
1262 cp.handle = ev->handle;
1263 cp.page = 0x01;
1264 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001265 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001266 goto unlock;
1267 }
1268
Johan Hedberg127178d2010-11-18 22:22:29 +02001269 if (!ev->status) {
1270 struct hci_cp_remote_name_req cp;
1271 memset(&cp, 0, sizeof(cp));
1272 bacpy(&cp.bdaddr, &conn->dst);
1273 cp.pscan_rep_mode = 0x02;
1274 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1275 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001276
Johan Hedberg127178d2010-11-18 22:22:29 +02001277 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001278 conn->state = BT_CONNECTED;
1279 hci_proto_connect_cfm(conn, ev->status);
1280 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001281 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001282
Johan Hedbergccd556f2010-11-10 17:11:51 +02001283unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001284 hci_dev_unlock(hdev);
1285}
1286
1287static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1288{
1289 BT_DBG("%s", hdev->name);
1290}
1291
1292static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1293{
1294 BT_DBG("%s", hdev->name);
1295}
1296
1297static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1298{
1299 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1300 __u16 opcode;
1301
1302 skb_pull(skb, sizeof(*ev));
1303
1304 opcode = __le16_to_cpu(ev->opcode);
1305
1306 switch (opcode) {
1307 case HCI_OP_INQUIRY_CANCEL:
1308 hci_cc_inquiry_cancel(hdev, skb);
1309 break;
1310
1311 case HCI_OP_EXIT_PERIODIC_INQ:
1312 hci_cc_exit_periodic_inq(hdev, skb);
1313 break;
1314
1315 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1316 hci_cc_remote_name_req_cancel(hdev, skb);
1317 break;
1318
1319 case HCI_OP_ROLE_DISCOVERY:
1320 hci_cc_role_discovery(hdev, skb);
1321 break;
1322
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001323 case HCI_OP_READ_LINK_POLICY:
1324 hci_cc_read_link_policy(hdev, skb);
1325 break;
1326
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001327 case HCI_OP_WRITE_LINK_POLICY:
1328 hci_cc_write_link_policy(hdev, skb);
1329 break;
1330
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001331 case HCI_OP_READ_DEF_LINK_POLICY:
1332 hci_cc_read_def_link_policy(hdev, skb);
1333 break;
1334
1335 case HCI_OP_WRITE_DEF_LINK_POLICY:
1336 hci_cc_write_def_link_policy(hdev, skb);
1337 break;
1338
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001339 case HCI_OP_RESET:
1340 hci_cc_reset(hdev, skb);
1341 break;
1342
1343 case HCI_OP_WRITE_LOCAL_NAME:
1344 hci_cc_write_local_name(hdev, skb);
1345 break;
1346
1347 case HCI_OP_READ_LOCAL_NAME:
1348 hci_cc_read_local_name(hdev, skb);
1349 break;
1350
1351 case HCI_OP_WRITE_AUTH_ENABLE:
1352 hci_cc_write_auth_enable(hdev, skb);
1353 break;
1354
1355 case HCI_OP_WRITE_ENCRYPT_MODE:
1356 hci_cc_write_encrypt_mode(hdev, skb);
1357 break;
1358
1359 case HCI_OP_WRITE_SCAN_ENABLE:
1360 hci_cc_write_scan_enable(hdev, skb);
1361 break;
1362
1363 case HCI_OP_READ_CLASS_OF_DEV:
1364 hci_cc_read_class_of_dev(hdev, skb);
1365 break;
1366
1367 case HCI_OP_WRITE_CLASS_OF_DEV:
1368 hci_cc_write_class_of_dev(hdev, skb);
1369 break;
1370
1371 case HCI_OP_READ_VOICE_SETTING:
1372 hci_cc_read_voice_setting(hdev, skb);
1373 break;
1374
1375 case HCI_OP_WRITE_VOICE_SETTING:
1376 hci_cc_write_voice_setting(hdev, skb);
1377 break;
1378
1379 case HCI_OP_HOST_BUFFER_SIZE:
1380 hci_cc_host_buffer_size(hdev, skb);
1381 break;
1382
Marcel Holtmann333140b2008-07-14 20:13:48 +02001383 case HCI_OP_READ_SSP_MODE:
1384 hci_cc_read_ssp_mode(hdev, skb);
1385 break;
1386
1387 case HCI_OP_WRITE_SSP_MODE:
1388 hci_cc_write_ssp_mode(hdev, skb);
1389 break;
1390
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001391 case HCI_OP_READ_LOCAL_VERSION:
1392 hci_cc_read_local_version(hdev, skb);
1393 break;
1394
1395 case HCI_OP_READ_LOCAL_COMMANDS:
1396 hci_cc_read_local_commands(hdev, skb);
1397 break;
1398
1399 case HCI_OP_READ_LOCAL_FEATURES:
1400 hci_cc_read_local_features(hdev, skb);
1401 break;
1402
1403 case HCI_OP_READ_BUFFER_SIZE:
1404 hci_cc_read_buffer_size(hdev, skb);
1405 break;
1406
1407 case HCI_OP_READ_BD_ADDR:
1408 hci_cc_read_bd_addr(hdev, skb);
1409 break;
1410
Johan Hedberg23bb5762010-12-21 23:01:27 +02001411 case HCI_OP_WRITE_CA_TIMEOUT:
1412 hci_cc_write_ca_timeout(hdev, skb);
1413 break;
1414
Johan Hedbergb0916ea2011-01-10 13:44:55 +02001415 case HCI_OP_DELETE_STORED_LINK_KEY:
1416 hci_cc_delete_stored_link_key(hdev, skb);
1417 break;
1418
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001419 default:
1420 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1421 break;
1422 }
1423
1424 if (ev->ncmd) {
1425 atomic_set(&hdev->cmd_cnt, 1);
1426 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001427 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001428 }
1429}
1430
1431static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1432{
1433 struct hci_ev_cmd_status *ev = (void *) skb->data;
1434 __u16 opcode;
1435
1436 skb_pull(skb, sizeof(*ev));
1437
1438 opcode = __le16_to_cpu(ev->opcode);
1439
1440 switch (opcode) {
1441 case HCI_OP_INQUIRY:
1442 hci_cs_inquiry(hdev, ev->status);
1443 break;
1444
1445 case HCI_OP_CREATE_CONN:
1446 hci_cs_create_conn(hdev, ev->status);
1447 break;
1448
1449 case HCI_OP_ADD_SCO:
1450 hci_cs_add_sco(hdev, ev->status);
1451 break;
1452
Marcel Holtmannf8558552008-07-14 20:13:49 +02001453 case HCI_OP_AUTH_REQUESTED:
1454 hci_cs_auth_requested(hdev, ev->status);
1455 break;
1456
1457 case HCI_OP_SET_CONN_ENCRYPT:
1458 hci_cs_set_conn_encrypt(hdev, ev->status);
1459 break;
1460
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001461 case HCI_OP_REMOTE_NAME_REQ:
1462 hci_cs_remote_name_req(hdev, ev->status);
1463 break;
1464
Marcel Holtmann769be972008-07-14 20:13:49 +02001465 case HCI_OP_READ_REMOTE_FEATURES:
1466 hci_cs_read_remote_features(hdev, ev->status);
1467 break;
1468
1469 case HCI_OP_READ_REMOTE_EXT_FEATURES:
1470 hci_cs_read_remote_ext_features(hdev, ev->status);
1471 break;
1472
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001473 case HCI_OP_SETUP_SYNC_CONN:
1474 hci_cs_setup_sync_conn(hdev, ev->status);
1475 break;
1476
1477 case HCI_OP_SNIFF_MODE:
1478 hci_cs_sniff_mode(hdev, ev->status);
1479 break;
1480
1481 case HCI_OP_EXIT_SNIFF_MODE:
1482 hci_cs_exit_sniff_mode(hdev, ev->status);
1483 break;
1484
1485 default:
1486 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1487 break;
1488 }
1489
1490 if (ev->ncmd) {
1491 atomic_set(&hdev->cmd_cnt, 1);
1492 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001493 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001494 }
1495}
1496
1497static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1498{
1499 struct hci_ev_role_change *ev = (void *) skb->data;
1500 struct hci_conn *conn;
1501
1502 BT_DBG("%s status %d", hdev->name, ev->status);
1503
1504 hci_dev_lock(hdev);
1505
1506 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1507 if (conn) {
1508 if (!ev->status) {
1509 if (ev->role)
1510 conn->link_mode &= ~HCI_LM_MASTER;
1511 else
1512 conn->link_mode |= HCI_LM_MASTER;
1513 }
1514
1515 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
1516
1517 hci_role_switch_cfm(conn, ev->status, ev->role);
1518 }
1519
1520 hci_dev_unlock(hdev);
1521}
1522
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
1524{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001525 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001526 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527 int i;
1528
1529 skb_pull(skb, sizeof(*ev));
1530
1531 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
1532
1533 if (skb->len < ev->num_hndl * 4) {
1534 BT_DBG("%s bad parameters", hdev->name);
1535 return;
1536 }
1537
1538 tasklet_disable(&hdev->tx_task);
1539
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001540 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 struct hci_conn *conn;
1542 __u16 handle, count;
1543
Harvey Harrison83985312008-05-02 16:25:46 -07001544 handle = get_unaligned_le16(ptr++);
1545 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546
1547 conn = hci_conn_hash_lookup_handle(hdev, handle);
1548 if (conn) {
1549 conn->sent -= count;
1550
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001551 if (conn->type == ACL_LINK) {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001552 hdev->acl_cnt += count;
1553 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554 hdev->acl_cnt = hdev->acl_pkts;
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001555 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001556 hdev->sco_cnt += count;
1557 if (hdev->sco_cnt > hdev->sco_pkts)
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001558 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559 }
1560 }
1561 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001562
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001563 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564
1565 tasklet_enable(&hdev->tx_task);
1566}
1567
Marcel Holtmann04837f62006-07-03 10:02:33 +02001568static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001570 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001571 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572
1573 BT_DBG("%s status %d", hdev->name, ev->status);
1574
1575 hci_dev_lock(hdev);
1576
Marcel Holtmann04837f62006-07-03 10:02:33 +02001577 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1578 if (conn) {
1579 conn->mode = ev->mode;
1580 conn->interval = __le16_to_cpu(ev->interval);
1581
1582 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
1583 if (conn->mode == HCI_CM_ACTIVE)
1584 conn->power_save = 1;
1585 else
1586 conn->power_save = 0;
1587 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001588
1589 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1590 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02001591 }
1592
1593 hci_dev_unlock(hdev);
1594}
1595
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1597{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001598 struct hci_ev_pin_code_req *ev = (void *) skb->data;
1599 struct hci_conn *conn;
1600
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001601 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001602
1603 hci_dev_lock(hdev);
1604
1605 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Marcel Holtmann3d7a9d12009-05-09 12:09:21 -07001606 if (conn && conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001607 hci_conn_hold(conn);
1608 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1609 hci_conn_put(conn);
1610 }
1611
Johan Hedberg03b555e2011-01-04 15:40:05 +02001612 if (!test_bit(HCI_PAIRABLE, &hdev->flags))
1613 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
1614 sizeof(ev->bdaddr), &ev->bdaddr);
1615
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001616 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617}
1618
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1620{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001621 BT_DBG("%s", hdev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622}
1623
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
1625{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001626 struct hci_ev_link_key_notify *ev = (void *) skb->data;
1627 struct hci_conn *conn;
1628
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001629 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001630
1631 hci_dev_lock(hdev);
1632
1633 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1634 if (conn) {
1635 hci_conn_hold(conn);
1636 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1637 hci_conn_put(conn);
1638 }
1639
1640 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641}
1642
Marcel Holtmann04837f62006-07-03 10:02:33 +02001643static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
1644{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001645 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001646 struct hci_conn *conn;
1647
1648 BT_DBG("%s status %d", hdev->name, ev->status);
1649
1650 hci_dev_lock(hdev);
1651
1652 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653 if (conn && !ev->status) {
1654 struct inquiry_entry *ie;
1655
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001656 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
1657 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658 ie->data.clock_offset = ev->clock_offset;
1659 ie->timestamp = jiffies;
1660 }
1661 }
1662
1663 hci_dev_unlock(hdev);
1664}
1665
Marcel Holtmanna8746412008-07-14 20:13:46 +02001666static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1667{
1668 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
1669 struct hci_conn *conn;
1670
1671 BT_DBG("%s status %d", hdev->name, ev->status);
1672
1673 hci_dev_lock(hdev);
1674
1675 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1676 if (conn && !ev->status)
1677 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
1678
1679 hci_dev_unlock(hdev);
1680}
1681
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001682static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
1683{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001684 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001685 struct inquiry_entry *ie;
1686
1687 BT_DBG("%s", hdev->name);
1688
1689 hci_dev_lock(hdev);
1690
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001691 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1692 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001693 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
1694 ie->timestamp = jiffies;
1695 }
1696
1697 hci_dev_unlock(hdev);
1698}
1699
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001700static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
1701{
1702 struct inquiry_data data;
1703 int num_rsp = *((__u8 *) skb->data);
1704
1705 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1706
1707 if (!num_rsp)
1708 return;
1709
1710 hci_dev_lock(hdev);
1711
1712 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
1713 struct inquiry_info_with_rssi_and_pscan_mode *info = (void *) (skb->data + 1);
1714
1715 for (; num_rsp; num_rsp--) {
1716 bacpy(&data.bdaddr, &info->bdaddr);
1717 data.pscan_rep_mode = info->pscan_rep_mode;
1718 data.pscan_period_mode = info->pscan_period_mode;
1719 data.pscan_mode = info->pscan_mode;
1720 memcpy(data.dev_class, info->dev_class, 3);
1721 data.clock_offset = info->clock_offset;
1722 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001723 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001724 info++;
1725 hci_inquiry_cache_update(hdev, &data);
1726 }
1727 } else {
1728 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
1729
1730 for (; num_rsp; num_rsp--) {
1731 bacpy(&data.bdaddr, &info->bdaddr);
1732 data.pscan_rep_mode = info->pscan_rep_mode;
1733 data.pscan_period_mode = info->pscan_period_mode;
1734 data.pscan_mode = 0x00;
1735 memcpy(data.dev_class, info->dev_class, 3);
1736 data.clock_offset = info->clock_offset;
1737 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001738 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001739 info++;
1740 hci_inquiry_cache_update(hdev, &data);
1741 }
1742 }
1743
1744 hci_dev_unlock(hdev);
1745}
1746
1747static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1748{
Marcel Holtmann41a96212008-07-14 20:13:48 +02001749 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
1750 struct hci_conn *conn;
1751
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001752 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02001753
Marcel Holtmann41a96212008-07-14 20:13:48 +02001754 hci_dev_lock(hdev);
1755
1756 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001757 if (!conn)
1758 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001759
Johan Hedbergccd556f2010-11-10 17:11:51 +02001760 if (!ev->status && ev->page == 0x01) {
1761 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001762
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001763 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
1764 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02001765 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02001766
Johan Hedbergccd556f2010-11-10 17:11:51 +02001767 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02001768 }
1769
Johan Hedbergccd556f2010-11-10 17:11:51 +02001770 if (conn->state != BT_CONFIG)
1771 goto unlock;
1772
Johan Hedberg127178d2010-11-18 22:22:29 +02001773 if (!ev->status) {
1774 struct hci_cp_remote_name_req cp;
1775 memset(&cp, 0, sizeof(cp));
1776 bacpy(&cp.bdaddr, &conn->dst);
1777 cp.pscan_rep_mode = 0x02;
1778 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1779 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001780
Johan Hedberg127178d2010-11-18 22:22:29 +02001781 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001782 conn->state = BT_CONNECTED;
1783 hci_proto_connect_cfm(conn, ev->status);
1784 hci_conn_put(conn);
1785 }
1786
1787unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02001788 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001789}
1790
1791static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1792{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001793 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
1794 struct hci_conn *conn;
1795
1796 BT_DBG("%s status %d", hdev->name, ev->status);
1797
1798 hci_dev_lock(hdev);
1799
1800 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02001801 if (!conn) {
1802 if (ev->link_type == ESCO_LINK)
1803 goto unlock;
1804
1805 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1806 if (!conn)
1807 goto unlock;
1808
1809 conn->type = SCO_LINK;
1810 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001811
Marcel Holtmann732547f2009-04-19 19:14:14 +02001812 switch (ev->status) {
1813 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001814 conn->handle = __le16_to_cpu(ev->handle);
1815 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001816
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001817 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001818 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02001819 break;
1820
Stephen Coe705e5712010-02-16 11:29:44 -05001821 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02001822 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08001823 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02001824 case 0x1f: /* Unspecified error */
1825 if (conn->out && conn->attempt < 2) {
1826 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
1827 (hdev->esco_type & EDR_ESCO_MASK);
1828 hci_setup_sync(conn, conn->link->handle);
1829 goto unlock;
1830 }
1831 /* fall through */
1832
1833 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001834 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02001835 break;
1836 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001837
1838 hci_proto_connect_cfm(conn, ev->status);
1839 if (ev->status)
1840 hci_conn_del(conn);
1841
1842unlock:
1843 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001844}
1845
1846static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
1847{
1848 BT_DBG("%s", hdev->name);
1849}
1850
Marcel Holtmann04837f62006-07-03 10:02:33 +02001851static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
1852{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001853 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001854 struct hci_conn *conn;
1855
1856 BT_DBG("%s status %d", hdev->name, ev->status);
1857
1858 hci_dev_lock(hdev);
1859
1860 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1861 if (conn) {
1862 }
1863
1864 hci_dev_unlock(hdev);
1865}
1866
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001867static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1868{
1869 struct inquiry_data data;
1870 struct extended_inquiry_info *info = (void *) (skb->data + 1);
1871 int num_rsp = *((__u8 *) skb->data);
1872
1873 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1874
1875 if (!num_rsp)
1876 return;
1877
1878 hci_dev_lock(hdev);
1879
1880 for (; num_rsp; num_rsp--) {
1881 bacpy(&data.bdaddr, &info->bdaddr);
1882 data.pscan_rep_mode = info->pscan_rep_mode;
1883 data.pscan_period_mode = info->pscan_period_mode;
1884 data.pscan_mode = 0x00;
1885 memcpy(data.dev_class, info->dev_class, 3);
1886 data.clock_offset = info->clock_offset;
1887 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001888 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001889 info++;
1890 hci_inquiry_cache_update(hdev, &data);
1891 }
1892
1893 hci_dev_unlock(hdev);
1894}
1895
Marcel Holtmann04936842008-07-14 20:13:48 +02001896static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1897{
1898 struct hci_ev_io_capa_request *ev = (void *) skb->data;
1899 struct hci_conn *conn;
1900
1901 BT_DBG("%s", hdev->name);
1902
1903 hci_dev_lock(hdev);
1904
1905 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02001906 if (!conn)
1907 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02001908
Johan Hedberg03b555e2011-01-04 15:40:05 +02001909 hci_conn_hold(conn);
1910
1911 if (!test_bit(HCI_MGMT, &hdev->flags))
1912 goto unlock;
1913
1914 if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
1915 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
1916 /* FIXME: Do IO capa response based on information
1917 * provided through the management interface */
1918 } else {
1919 struct hci_cp_io_capability_neg_reply cp;
1920
1921 bacpy(&cp.bdaddr, &ev->bdaddr);
1922 cp.reason = 0x16; /* Pairing not allowed */
1923
1924 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
1925 sizeof(cp), &cp);
1926 }
1927
1928unlock:
1929 hci_dev_unlock(hdev);
1930}
1931
1932static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
1933{
1934 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
1935 struct hci_conn *conn;
1936
1937 BT_DBG("%s", hdev->name);
1938
1939 hci_dev_lock(hdev);
1940
1941 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1942 if (!conn)
1943 goto unlock;
1944
1945 hci_conn_hold(conn);
1946
1947 conn->remote_cap = ev->capability;
1948 conn->remote_oob = ev->oob_data;
1949 conn->remote_auth = ev->authentication;
1950
1951unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02001952 hci_dev_unlock(hdev);
1953}
1954
1955static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1956{
1957 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
1958 struct hci_conn *conn;
1959
1960 BT_DBG("%s", hdev->name);
1961
1962 hci_dev_lock(hdev);
1963
1964 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1965 if (conn)
1966 hci_conn_put(conn);
1967
1968 hci_dev_unlock(hdev);
1969}
1970
Marcel Holtmann41a96212008-07-14 20:13:48 +02001971static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1972{
1973 struct hci_ev_remote_host_features *ev = (void *) skb->data;
1974 struct inquiry_entry *ie;
1975
1976 BT_DBG("%s", hdev->name);
1977
1978 hci_dev_lock(hdev);
1979
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001980 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1981 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02001982 ie->data.ssp_mode = (ev->features[0] & 0x01);
1983
1984 hci_dev_unlock(hdev);
1985}
1986
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
1988{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001989 struct hci_event_hdr *hdr = (void *) skb->data;
1990 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991
1992 skb_pull(skb, HCI_EVENT_HDR_SIZE);
1993
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001994 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001995 case HCI_EV_INQUIRY_COMPLETE:
1996 hci_inquiry_complete_evt(hdev, skb);
1997 break;
1998
1999 case HCI_EV_INQUIRY_RESULT:
2000 hci_inquiry_result_evt(hdev, skb);
2001 break;
2002
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002003 case HCI_EV_CONN_COMPLETE:
2004 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02002005 break;
2006
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007 case HCI_EV_CONN_REQUEST:
2008 hci_conn_request_evt(hdev, skb);
2009 break;
2010
Linus Torvalds1da177e2005-04-16 15:20:36 -07002011 case HCI_EV_DISCONN_COMPLETE:
2012 hci_disconn_complete_evt(hdev, skb);
2013 break;
2014
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015 case HCI_EV_AUTH_COMPLETE:
2016 hci_auth_complete_evt(hdev, skb);
2017 break;
2018
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002019 case HCI_EV_REMOTE_NAME:
2020 hci_remote_name_evt(hdev, skb);
2021 break;
2022
Linus Torvalds1da177e2005-04-16 15:20:36 -07002023 case HCI_EV_ENCRYPT_CHANGE:
2024 hci_encrypt_change_evt(hdev, skb);
2025 break;
2026
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002027 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
2028 hci_change_link_key_complete_evt(hdev, skb);
2029 break;
2030
2031 case HCI_EV_REMOTE_FEATURES:
2032 hci_remote_features_evt(hdev, skb);
2033 break;
2034
2035 case HCI_EV_REMOTE_VERSION:
2036 hci_remote_version_evt(hdev, skb);
2037 break;
2038
2039 case HCI_EV_QOS_SETUP_COMPLETE:
2040 hci_qos_setup_complete_evt(hdev, skb);
2041 break;
2042
2043 case HCI_EV_CMD_COMPLETE:
2044 hci_cmd_complete_evt(hdev, skb);
2045 break;
2046
2047 case HCI_EV_CMD_STATUS:
2048 hci_cmd_status_evt(hdev, skb);
2049 break;
2050
2051 case HCI_EV_ROLE_CHANGE:
2052 hci_role_change_evt(hdev, skb);
2053 break;
2054
2055 case HCI_EV_NUM_COMP_PKTS:
2056 hci_num_comp_pkts_evt(hdev, skb);
2057 break;
2058
2059 case HCI_EV_MODE_CHANGE:
2060 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061 break;
2062
2063 case HCI_EV_PIN_CODE_REQ:
2064 hci_pin_code_request_evt(hdev, skb);
2065 break;
2066
2067 case HCI_EV_LINK_KEY_REQ:
2068 hci_link_key_request_evt(hdev, skb);
2069 break;
2070
2071 case HCI_EV_LINK_KEY_NOTIFY:
2072 hci_link_key_notify_evt(hdev, skb);
2073 break;
2074
2075 case HCI_EV_CLOCK_OFFSET:
2076 hci_clock_offset_evt(hdev, skb);
2077 break;
2078
Marcel Holtmanna8746412008-07-14 20:13:46 +02002079 case HCI_EV_PKT_TYPE_CHANGE:
2080 hci_pkt_type_change_evt(hdev, skb);
2081 break;
2082
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002083 case HCI_EV_PSCAN_REP_MODE:
2084 hci_pscan_rep_mode_evt(hdev, skb);
2085 break;
2086
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002087 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
2088 hci_inquiry_result_with_rssi_evt(hdev, skb);
2089 break;
2090
2091 case HCI_EV_REMOTE_EXT_FEATURES:
2092 hci_remote_ext_features_evt(hdev, skb);
2093 break;
2094
2095 case HCI_EV_SYNC_CONN_COMPLETE:
2096 hci_sync_conn_complete_evt(hdev, skb);
2097 break;
2098
2099 case HCI_EV_SYNC_CONN_CHANGED:
2100 hci_sync_conn_changed_evt(hdev, skb);
2101 break;
2102
Marcel Holtmann04837f62006-07-03 10:02:33 +02002103 case HCI_EV_SNIFF_SUBRATE:
2104 hci_sniff_subrate_evt(hdev, skb);
2105 break;
2106
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002107 case HCI_EV_EXTENDED_INQUIRY_RESULT:
2108 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109 break;
2110
Marcel Holtmann04936842008-07-14 20:13:48 +02002111 case HCI_EV_IO_CAPA_REQUEST:
2112 hci_io_capa_request_evt(hdev, skb);
2113 break;
2114
Johan Hedberg03b555e2011-01-04 15:40:05 +02002115 case HCI_EV_IO_CAPA_REPLY:
2116 hci_io_capa_reply_evt(hdev, skb);
2117 break;
2118
Marcel Holtmann04936842008-07-14 20:13:48 +02002119 case HCI_EV_SIMPLE_PAIR_COMPLETE:
2120 hci_simple_pair_complete_evt(hdev, skb);
2121 break;
2122
Marcel Holtmann41a96212008-07-14 20:13:48 +02002123 case HCI_EV_REMOTE_HOST_FEATURES:
2124 hci_remote_host_features_evt(hdev, skb);
2125 break;
2126
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002127 default:
2128 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129 break;
2130 }
2131
2132 kfree_skb(skb);
2133 hdev->stat.evt_rx++;
2134}
2135
2136/* Generate internal stack event */
2137void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
2138{
2139 struct hci_event_hdr *hdr;
2140 struct hci_ev_stack_internal *ev;
2141 struct sk_buff *skb;
2142
2143 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
2144 if (!skb)
2145 return;
2146
2147 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
2148 hdr->evt = HCI_EV_STACK_INTERNAL;
2149 hdr->plen = sizeof(*ev) + dlen;
2150
2151 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
2152 ev->type = type;
2153 memcpy(ev->data, data, dlen);
2154
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002155 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07002156 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002157
Marcel Holtmann0d48d932005-08-09 20:30:28 -07002158 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002159 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02002160 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161 kfree_skb(skb);
2162}