blob: f55004af0558a66eee1d5853c79aeac752152664 [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);
277
278 clear_bit(HCI_PSCAN, &hdev->flags);
279 clear_bit(HCI_ISCAN, &hdev->flags);
280
Johan Hedberg73f22f62010-12-29 16:00:25 +0200281 if (param & SCAN_INQUIRY) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200282 set_bit(HCI_ISCAN, &hdev->flags);
Johan Hedberg73f22f62010-12-29 16:00:25 +0200283 mgmt_discoverable(hdev->id, 1);
284 } else
285 mgmt_discoverable(hdev->id, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200286
287 if (param & SCAN_PAGE)
288 set_bit(HCI_PSCAN, &hdev->flags);
289 }
290
Johan Hedberg23bb5762010-12-21 23:01:27 +0200291 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200292}
293
294static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
295{
296 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
297
298 BT_DBG("%s status 0x%x", hdev->name, rp->status);
299
300 if (rp->status)
301 return;
302
303 memcpy(hdev->dev_class, rp->dev_class, 3);
304
305 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
306 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
307}
308
309static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
310{
311 __u8 status = *((__u8 *) skb->data);
312 void *sent;
313
314 BT_DBG("%s status 0x%x", hdev->name, status);
315
Marcel Holtmannf383f272008-07-14 20:13:47 +0200316 if (status)
317 return;
318
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200319 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
320 if (!sent)
321 return;
322
Marcel Holtmannf383f272008-07-14 20:13:47 +0200323 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200324}
325
326static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
327{
328 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200330
331 BT_DBG("%s status 0x%x", hdev->name, rp->status);
332
333 if (rp->status)
334 return;
335
336 setting = __le16_to_cpu(rp->voice_setting);
337
Marcel Holtmannf383f272008-07-14 20:13:47 +0200338 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200339 return;
340
341 hdev->voice_setting = setting;
342
343 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
344
345 if (hdev->notify) {
346 tasklet_disable(&hdev->tx_task);
347 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
348 tasklet_enable(&hdev->tx_task);
349 }
350}
351
352static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
353{
354 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200355 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 void *sent;
357
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200358 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359
Marcel Holtmannf383f272008-07-14 20:13:47 +0200360 if (status)
361 return;
362
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200363 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
364 if (!sent)
365 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366
Marcel Holtmannf383f272008-07-14 20:13:47 +0200367 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368
Marcel Holtmannf383f272008-07-14 20:13:47 +0200369 if (hdev->voice_setting == setting)
370 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371
Marcel Holtmannf383f272008-07-14 20:13:47 +0200372 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373
Marcel Holtmannf383f272008-07-14 20:13:47 +0200374 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
375
376 if (hdev->notify) {
377 tasklet_disable(&hdev->tx_task);
378 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
379 tasklet_enable(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 }
381}
382
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200383static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200385 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200387 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388
Johan Hedberg23bb5762010-12-21 23:01:27 +0200389 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390}
391
Marcel Holtmann333140b2008-07-14 20:13:48 +0200392static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
393{
394 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
395
396 BT_DBG("%s status 0x%x", hdev->name, rp->status);
397
398 if (rp->status)
399 return;
400
401 hdev->ssp_mode = rp->mode;
402}
403
404static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
405{
406 __u8 status = *((__u8 *) skb->data);
407 void *sent;
408
409 BT_DBG("%s status 0x%x", hdev->name, status);
410
411 if (status)
412 return;
413
414 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
415 if (!sent)
416 return;
417
418 hdev->ssp_mode = *((__u8 *) sent);
419}
420
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200421static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
422{
423 struct hci_rp_read_local_version *rp = (void *) skb->data;
424
425 BT_DBG("%s status 0x%x", hdev->name, rp->status);
426
427 if (rp->status)
428 return;
429
430 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200431 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
432 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200433
434 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
435 hdev->manufacturer,
436 hdev->hci_ver, hdev->hci_rev);
437}
438
439static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
440{
441 struct hci_rp_read_local_commands *rp = (void *) skb->data;
442
443 BT_DBG("%s status 0x%x", hdev->name, rp->status);
444
445 if (rp->status)
446 return;
447
448 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
449}
450
451static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
452{
453 struct hci_rp_read_local_features *rp = (void *) skb->data;
454
455 BT_DBG("%s status 0x%x", hdev->name, rp->status);
456
457 if (rp->status)
458 return;
459
460 memcpy(hdev->features, rp->features, 8);
461
462 /* Adjust default settings according to features
463 * supported by device. */
464
465 if (hdev->features[0] & LMP_3SLOT)
466 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
467
468 if (hdev->features[0] & LMP_5SLOT)
469 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
470
471 if (hdev->features[1] & LMP_HV2) {
472 hdev->pkt_type |= (HCI_HV2);
473 hdev->esco_type |= (ESCO_HV2);
474 }
475
476 if (hdev->features[1] & LMP_HV3) {
477 hdev->pkt_type |= (HCI_HV3);
478 hdev->esco_type |= (ESCO_HV3);
479 }
480
481 if (hdev->features[3] & LMP_ESCO)
482 hdev->esco_type |= (ESCO_EV3);
483
484 if (hdev->features[4] & LMP_EV4)
485 hdev->esco_type |= (ESCO_EV4);
486
487 if (hdev->features[4] & LMP_EV5)
488 hdev->esco_type |= (ESCO_EV5);
489
Marcel Holtmannefc76882009-02-06 09:13:37 +0100490 if (hdev->features[5] & LMP_EDR_ESCO_2M)
491 hdev->esco_type |= (ESCO_2EV3);
492
493 if (hdev->features[5] & LMP_EDR_ESCO_3M)
494 hdev->esco_type |= (ESCO_3EV3);
495
496 if (hdev->features[5] & LMP_EDR_3S_ESCO)
497 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
498
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200499 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
500 hdev->features[0], hdev->features[1],
501 hdev->features[2], hdev->features[3],
502 hdev->features[4], hdev->features[5],
503 hdev->features[6], hdev->features[7]);
504}
505
506static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
507{
508 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
509
510 BT_DBG("%s status 0x%x", hdev->name, rp->status);
511
512 if (rp->status)
513 return;
514
515 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
516 hdev->sco_mtu = rp->sco_mtu;
517 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
518 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
519
520 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
521 hdev->sco_mtu = 64;
522 hdev->sco_pkts = 8;
523 }
524
525 hdev->acl_cnt = hdev->acl_pkts;
526 hdev->sco_cnt = hdev->sco_pkts;
527
528 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
529 hdev->acl_mtu, hdev->acl_pkts,
530 hdev->sco_mtu, hdev->sco_pkts);
531}
532
533static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
534{
535 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
536
537 BT_DBG("%s status 0x%x", hdev->name, rp->status);
538
539 if (!rp->status)
540 bacpy(&hdev->bdaddr, &rp->bdaddr);
541
Johan Hedberg23bb5762010-12-21 23:01:27 +0200542 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
543}
544
545static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
546{
547 __u8 status = *((__u8 *) skb->data);
548
549 BT_DBG("%s status 0x%x", hdev->name, status);
550
551 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200552}
553
554static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
555{
556 BT_DBG("%s status 0x%x", hdev->name, status);
557
558 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +0200559 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200560
561 hci_conn_check_pending(hdev);
562 } else
563 set_bit(HCI_INQUIRY, &hdev->flags);
564}
565
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
567{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200568 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200571 BT_DBG("%s status 0x%x", hdev->name, status);
572
573 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 if (!cp)
575 return;
576
577 hci_dev_lock(hdev);
578
579 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
580
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200581 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582
583 if (status) {
584 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200585 if (status != 0x0c || conn->attempt > 2) {
586 conn->state = BT_CLOSED;
587 hci_proto_connect_cfm(conn, status);
588 hci_conn_del(conn);
589 } else
590 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591 }
592 } else {
593 if (!conn) {
594 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
595 if (conn) {
596 conn->out = 1;
597 conn->link_mode |= HCI_LM_MASTER;
598 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -0300599 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 }
601 }
602
603 hci_dev_unlock(hdev);
604}
605
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200606static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200608 struct hci_cp_add_sco *cp;
609 struct hci_conn *acl, *sco;
610 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200612 BT_DBG("%s status 0x%x", hdev->name, status);
613
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200614 if (!status)
615 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200617 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
618 if (!cp)
619 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200621 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200623 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100624
625 hci_dev_lock(hdev);
626
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200627 acl = hci_conn_hash_lookup_handle(hdev, handle);
628 if (acl && (sco = acl->link)) {
629 sco->state = BT_CLOSED;
630
631 hci_proto_connect_cfm(sco, status);
632 hci_conn_del(sco);
633 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100634
635 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636}
637
Marcel Holtmannf8558552008-07-14 20:13:49 +0200638static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
639{
640 struct hci_cp_auth_requested *cp;
641 struct hci_conn *conn;
642
643 BT_DBG("%s status 0x%x", hdev->name, status);
644
645 if (!status)
646 return;
647
648 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
649 if (!cp)
650 return;
651
652 hci_dev_lock(hdev);
653
654 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
655 if (conn) {
656 if (conn->state == BT_CONFIG) {
657 hci_proto_connect_cfm(conn, status);
658 hci_conn_put(conn);
659 }
660 }
661
662 hci_dev_unlock(hdev);
663}
664
665static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
666{
667 struct hci_cp_set_conn_encrypt *cp;
668 struct hci_conn *conn;
669
670 BT_DBG("%s status 0x%x", hdev->name, status);
671
672 if (!status)
673 return;
674
675 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
676 if (!cp)
677 return;
678
679 hci_dev_lock(hdev);
680
681 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
682 if (conn) {
683 if (conn->state == BT_CONFIG) {
684 hci_proto_connect_cfm(conn, status);
685 hci_conn_put(conn);
686 }
687 }
688
689 hci_dev_unlock(hdev);
690}
691
Johan Hedberg127178d2010-11-18 22:22:29 +0200692static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Johan Hedberg392599b2010-11-18 22:22:28 +0200693 struct hci_conn *conn)
694{
Johan Hedberg392599b2010-11-18 22:22:28 +0200695 if (conn->state != BT_CONFIG || !conn->out)
696 return 0;
697
Johan Hedberg765c2a92011-01-19 12:06:52 +0530698 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +0200699 return 0;
700
701 /* Only request authentication for SSP connections or non-SSP
702 * devices with sec_level HIGH */
703 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
Johan Hedberg765c2a92011-01-19 12:06:52 +0530704 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +0200705 return 0;
706
Johan Hedberg392599b2010-11-18 22:22:28 +0200707 return 1;
708}
709
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200710static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
711{
Johan Hedberg127178d2010-11-18 22:22:29 +0200712 struct hci_cp_remote_name_req *cp;
713 struct hci_conn *conn;
714
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200715 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +0200716
717 /* If successful wait for the name req complete event before
718 * checking for the need to do authentication */
719 if (!status)
720 return;
721
722 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
723 if (!cp)
724 return;
725
726 hci_dev_lock(hdev);
727
728 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
729 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
730 struct hci_cp_auth_requested cp;
731 cp.handle = __cpu_to_le16(conn->handle);
732 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
733 }
734
735 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200736}
737
Marcel Holtmann769be972008-07-14 20:13:49 +0200738static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
739{
740 struct hci_cp_read_remote_features *cp;
741 struct hci_conn *conn;
742
743 BT_DBG("%s status 0x%x", hdev->name, status);
744
745 if (!status)
746 return;
747
748 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
749 if (!cp)
750 return;
751
752 hci_dev_lock(hdev);
753
754 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
755 if (conn) {
756 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +0200757 hci_proto_connect_cfm(conn, status);
758 hci_conn_put(conn);
759 }
760 }
761
762 hci_dev_unlock(hdev);
763}
764
765static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
766{
767 struct hci_cp_read_remote_ext_features *cp;
768 struct hci_conn *conn;
769
770 BT_DBG("%s status 0x%x", hdev->name, status);
771
772 if (!status)
773 return;
774
775 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
776 if (!cp)
777 return;
778
779 hci_dev_lock(hdev);
780
781 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
782 if (conn) {
783 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +0200784 hci_proto_connect_cfm(conn, status);
785 hci_conn_put(conn);
786 }
787 }
788
789 hci_dev_unlock(hdev);
790}
791
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200792static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
793{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200794 struct hci_cp_setup_sync_conn *cp;
795 struct hci_conn *acl, *sco;
796 __u16 handle;
797
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200798 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200799
800 if (!status)
801 return;
802
803 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
804 if (!cp)
805 return;
806
807 handle = __le16_to_cpu(cp->handle);
808
809 BT_DBG("%s handle %d", hdev->name, handle);
810
811 hci_dev_lock(hdev);
812
813 acl = hci_conn_hash_lookup_handle(hdev, handle);
814 if (acl && (sco = acl->link)) {
815 sco->state = BT_CLOSED;
816
817 hci_proto_connect_cfm(sco, status);
818 hci_conn_del(sco);
819 }
820
821 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200822}
823
824static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
825{
826 struct hci_cp_sniff_mode *cp;
827 struct hci_conn *conn;
828
829 BT_DBG("%s status 0x%x", hdev->name, status);
830
831 if (!status)
832 return;
833
834 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
835 if (!cp)
836 return;
837
838 hci_dev_lock(hdev);
839
840 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400841 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200842 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
843
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400844 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
845 hci_sco_setup(conn, status);
846 }
847
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200848 hci_dev_unlock(hdev);
849}
850
851static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
852{
853 struct hci_cp_exit_sniff_mode *cp;
854 struct hci_conn *conn;
855
856 BT_DBG("%s status 0x%x", hdev->name, status);
857
858 if (!status)
859 return;
860
861 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
862 if (!cp)
863 return;
864
865 hci_dev_lock(hdev);
866
867 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400868 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200869 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
870
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400871 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
872 hci_sco_setup(conn, status);
873 }
874
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200875 hci_dev_unlock(hdev);
876}
877
878static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
879{
880 __u8 status = *((__u8 *) skb->data);
881
882 BT_DBG("%s status %d", hdev->name, status);
883
884 clear_bit(HCI_INQUIRY, &hdev->flags);
885
Johan Hedberg23bb5762010-12-21 23:01:27 +0200886 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200887
888 hci_conn_check_pending(hdev);
889}
890
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
892{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700893 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200894 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895 int num_rsp = *((__u8 *) skb->data);
896
897 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
898
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700899 if (!num_rsp)
900 return;
901
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700903
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904 for (; num_rsp; num_rsp--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 bacpy(&data.bdaddr, &info->bdaddr);
906 data.pscan_rep_mode = info->pscan_rep_mode;
907 data.pscan_period_mode = info->pscan_period_mode;
908 data.pscan_mode = info->pscan_mode;
909 memcpy(data.dev_class, info->dev_class, 3);
910 data.clock_offset = info->clock_offset;
911 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +0200912 data.ssp_mode = 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913 info++;
914 hci_inquiry_cache_update(hdev, &data);
915 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700916
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 hci_dev_unlock(hdev);
918}
919
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200920static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200922 struct hci_ev_conn_complete *ev = (void *) skb->data;
923 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200925 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700926
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700928
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200929 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +0200930 if (!conn) {
931 if (ev->link_type != SCO_LINK)
932 goto unlock;
933
934 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
935 if (!conn)
936 goto unlock;
937
938 conn->type = SCO_LINK;
939 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700940
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200941 if (!ev->status) {
942 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +0200943
944 if (conn->type == ACL_LINK) {
945 conn->state = BT_CONFIG;
946 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +0200947 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +0200948 } else
949 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200950
Marcel Holtmann9eba32b2009-08-22 14:19:26 -0700951 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +0200952 hci_conn_add_sysfs(conn);
953
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200954 if (test_bit(HCI_AUTH, &hdev->flags))
955 conn->link_mode |= HCI_LM_AUTH;
956
957 if (test_bit(HCI_ENCRYPT, &hdev->flags))
958 conn->link_mode |= HCI_LM_ENCRYPT;
959
960 /* Get remote features */
961 if (conn->type == ACL_LINK) {
962 struct hci_cp_read_remote_features cp;
963 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +0200964 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
965 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700966 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700967
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200968 /* Set packet type for incoming connection */
Marcel Holtmanna8746412008-07-14 20:13:46 +0200969 if (!conn->out && hdev->hci_ver < 3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200970 struct hci_cp_change_conn_ptype cp;
971 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +0200972 cp.pkt_type = cpu_to_le16(conn->pkt_type);
973 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
974 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200975 }
976 } else
977 conn->state = BT_CLOSED;
978
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400979 if (conn->type == ACL_LINK)
980 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700981
Marcel Holtmann769be972008-07-14 20:13:49 +0200982 if (ev->status) {
983 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200984 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +0100985 } else if (ev->link_type != ACL_LINK)
986 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200987
988unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200990
991 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992}
993
Linus Torvalds1da177e2005-04-16 15:20:36 -0700994static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
995{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200996 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997 int mask = hdev->link_mode;
998
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200999 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1000 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001
1002 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1003
Johan Hedbergf0358562010-05-18 13:20:32 +02001004 if ((mask & HCI_LM_ACCEPT) && !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001006 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008
1009 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001010
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001011 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1012 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001013 memcpy(ie->data.dev_class, ev->dev_class, 3);
1014
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1016 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001017 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1018 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001019 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 hci_dev_unlock(hdev);
1021 return;
1022 }
1023 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001024
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 memcpy(conn->dev_class, ev->dev_class, 3);
1026 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001027
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 hci_dev_unlock(hdev);
1029
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001030 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1031 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001033 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001035 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1036 cp.role = 0x00; /* Become master */
1037 else
1038 cp.role = 0x01; /* Remain slave */
1039
1040 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1041 sizeof(cp), &cp);
1042 } else {
1043 struct hci_cp_accept_sync_conn_req cp;
1044
1045 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001046 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001047
1048 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1049 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1050 cp.max_latency = cpu_to_le16(0xffff);
1051 cp.content_format = cpu_to_le16(hdev->voice_setting);
1052 cp.retrans_effort = 0xff;
1053
1054 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1055 sizeof(cp), &cp);
1056 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 } else {
1058 /* Connection rejected */
1059 struct hci_cp_reject_conn_req cp;
1060
1061 bacpy(&cp.bdaddr, &ev->bdaddr);
1062 cp.reason = 0x0f;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001063 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 }
1065}
1066
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1068{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001069 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001070 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071
1072 BT_DBG("%s status %d", hdev->name, ev->status);
1073
1074 if (ev->status)
1075 return;
1076
1077 hci_dev_lock(hdev);
1078
Marcel Holtmann04837f62006-07-03 10:02:33 +02001079 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 if (conn) {
1081 conn->state = BT_CLOSED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001082
Marcel Holtmann2950f212009-02-12 14:02:50 +01001083 hci_proto_disconn_cfm(conn, ev->reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084 hci_conn_del(conn);
1085 }
1086
1087 hci_dev_unlock(hdev);
1088}
1089
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001090static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1091{
1092 struct hci_ev_auth_complete *ev = (void *) skb->data;
1093 struct hci_conn *conn;
1094
1095 BT_DBG("%s status %d", hdev->name, ev->status);
1096
1097 hci_dev_lock(hdev);
1098
1099 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1100 if (conn) {
Johan Hedberg765c2a92011-01-19 12:06:52 +05301101 if (!ev->status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001102 conn->link_mode |= HCI_LM_AUTH;
Johan Hedberg765c2a92011-01-19 12:06:52 +05301103 conn->sec_level = conn->pending_sec_level;
1104 } else
Johan Hedbergda213f42010-06-18 11:08:56 +03001105 conn->sec_level = BT_SECURITY_LOW;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001106
1107 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1108
Marcel Holtmannf8558552008-07-14 20:13:49 +02001109 if (conn->state == BT_CONFIG) {
1110 if (!ev->status && hdev->ssp_mode > 0 &&
1111 conn->ssp_mode > 0) {
1112 struct hci_cp_set_conn_encrypt cp;
1113 cp.handle = ev->handle;
1114 cp.encrypt = 0x01;
1115 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1116 sizeof(cp), &cp);
1117 } else {
1118 conn->state = BT_CONNECTED;
1119 hci_proto_connect_cfm(conn, ev->status);
1120 hci_conn_put(conn);
1121 }
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001122 } else {
Marcel Holtmannf8558552008-07-14 20:13:49 +02001123 hci_auth_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001124
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001125 hci_conn_hold(conn);
1126 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1127 hci_conn_put(conn);
1128 }
1129
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001130 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1131 if (!ev->status) {
1132 struct hci_cp_set_conn_encrypt cp;
Marcel Holtmannf8558552008-07-14 20:13:49 +02001133 cp.handle = ev->handle;
1134 cp.encrypt = 0x01;
1135 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1136 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001137 } else {
1138 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1139 hci_encrypt_cfm(conn, ev->status, 0x00);
1140 }
1141 }
1142 }
1143
1144 hci_dev_unlock(hdev);
1145}
1146
1147static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1148{
Johan Hedberg127178d2010-11-18 22:22:29 +02001149 struct hci_ev_remote_name *ev = (void *) skb->data;
1150 struct hci_conn *conn;
1151
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001152 BT_DBG("%s", hdev->name);
1153
1154 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001155
1156 hci_dev_lock(hdev);
1157
1158 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1159 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
1160 struct hci_cp_auth_requested cp;
1161 cp.handle = __cpu_to_le16(conn->handle);
1162 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1163 }
1164
1165 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001166}
1167
1168static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1169{
1170 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1171 struct hci_conn *conn;
1172
1173 BT_DBG("%s status %d", hdev->name, ev->status);
1174
1175 hci_dev_lock(hdev);
1176
1177 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1178 if (conn) {
1179 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001180 if (ev->encrypt) {
1181 /* Encryption implies authentication */
1182 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001183 conn->link_mode |= HCI_LM_ENCRYPT;
Marcel Holtmannae293192008-07-14 20:13:45 +02001184 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001185 conn->link_mode &= ~HCI_LM_ENCRYPT;
1186 }
1187
1188 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1189
Marcel Holtmannf8558552008-07-14 20:13:49 +02001190 if (conn->state == BT_CONFIG) {
1191 if (!ev->status)
1192 conn->state = BT_CONNECTED;
1193
1194 hci_proto_connect_cfm(conn, ev->status);
1195 hci_conn_put(conn);
1196 } else
1197 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001198 }
1199
1200 hci_dev_unlock(hdev);
1201}
1202
1203static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1204{
1205 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1206 struct hci_conn *conn;
1207
1208 BT_DBG("%s status %d", hdev->name, ev->status);
1209
1210 hci_dev_lock(hdev);
1211
1212 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1213 if (conn) {
1214 if (!ev->status)
1215 conn->link_mode |= HCI_LM_SECURE;
1216
1217 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1218
1219 hci_key_change_cfm(conn, ev->status);
1220 }
1221
1222 hci_dev_unlock(hdev);
1223}
1224
1225static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1226{
1227 struct hci_ev_remote_features *ev = (void *) skb->data;
1228 struct hci_conn *conn;
1229
1230 BT_DBG("%s status %d", hdev->name, ev->status);
1231
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001232 hci_dev_lock(hdev);
1233
1234 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001235 if (!conn)
1236 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001237
Johan Hedbergccd556f2010-11-10 17:11:51 +02001238 if (!ev->status)
1239 memcpy(conn->features, ev->features, 8);
1240
1241 if (conn->state != BT_CONFIG)
1242 goto unlock;
1243
1244 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1245 struct hci_cp_read_remote_ext_features cp;
1246 cp.handle = ev->handle;
1247 cp.page = 0x01;
1248 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001249 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001250 goto unlock;
1251 }
1252
Johan Hedberg127178d2010-11-18 22:22:29 +02001253 if (!ev->status) {
1254 struct hci_cp_remote_name_req cp;
1255 memset(&cp, 0, sizeof(cp));
1256 bacpy(&cp.bdaddr, &conn->dst);
1257 cp.pscan_rep_mode = 0x02;
1258 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1259 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001260
Johan Hedberg127178d2010-11-18 22:22:29 +02001261 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001262 conn->state = BT_CONNECTED;
1263 hci_proto_connect_cfm(conn, ev->status);
1264 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001265 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001266
Johan Hedbergccd556f2010-11-10 17:11:51 +02001267unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001268 hci_dev_unlock(hdev);
1269}
1270
1271static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1272{
1273 BT_DBG("%s", hdev->name);
1274}
1275
1276static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1277{
1278 BT_DBG("%s", hdev->name);
1279}
1280
1281static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1282{
1283 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1284 __u16 opcode;
1285
1286 skb_pull(skb, sizeof(*ev));
1287
1288 opcode = __le16_to_cpu(ev->opcode);
1289
1290 switch (opcode) {
1291 case HCI_OP_INQUIRY_CANCEL:
1292 hci_cc_inquiry_cancel(hdev, skb);
1293 break;
1294
1295 case HCI_OP_EXIT_PERIODIC_INQ:
1296 hci_cc_exit_periodic_inq(hdev, skb);
1297 break;
1298
1299 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1300 hci_cc_remote_name_req_cancel(hdev, skb);
1301 break;
1302
1303 case HCI_OP_ROLE_DISCOVERY:
1304 hci_cc_role_discovery(hdev, skb);
1305 break;
1306
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001307 case HCI_OP_READ_LINK_POLICY:
1308 hci_cc_read_link_policy(hdev, skb);
1309 break;
1310
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001311 case HCI_OP_WRITE_LINK_POLICY:
1312 hci_cc_write_link_policy(hdev, skb);
1313 break;
1314
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001315 case HCI_OP_READ_DEF_LINK_POLICY:
1316 hci_cc_read_def_link_policy(hdev, skb);
1317 break;
1318
1319 case HCI_OP_WRITE_DEF_LINK_POLICY:
1320 hci_cc_write_def_link_policy(hdev, skb);
1321 break;
1322
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001323 case HCI_OP_RESET:
1324 hci_cc_reset(hdev, skb);
1325 break;
1326
1327 case HCI_OP_WRITE_LOCAL_NAME:
1328 hci_cc_write_local_name(hdev, skb);
1329 break;
1330
1331 case HCI_OP_READ_LOCAL_NAME:
1332 hci_cc_read_local_name(hdev, skb);
1333 break;
1334
1335 case HCI_OP_WRITE_AUTH_ENABLE:
1336 hci_cc_write_auth_enable(hdev, skb);
1337 break;
1338
1339 case HCI_OP_WRITE_ENCRYPT_MODE:
1340 hci_cc_write_encrypt_mode(hdev, skb);
1341 break;
1342
1343 case HCI_OP_WRITE_SCAN_ENABLE:
1344 hci_cc_write_scan_enable(hdev, skb);
1345 break;
1346
1347 case HCI_OP_READ_CLASS_OF_DEV:
1348 hci_cc_read_class_of_dev(hdev, skb);
1349 break;
1350
1351 case HCI_OP_WRITE_CLASS_OF_DEV:
1352 hci_cc_write_class_of_dev(hdev, skb);
1353 break;
1354
1355 case HCI_OP_READ_VOICE_SETTING:
1356 hci_cc_read_voice_setting(hdev, skb);
1357 break;
1358
1359 case HCI_OP_WRITE_VOICE_SETTING:
1360 hci_cc_write_voice_setting(hdev, skb);
1361 break;
1362
1363 case HCI_OP_HOST_BUFFER_SIZE:
1364 hci_cc_host_buffer_size(hdev, skb);
1365 break;
1366
Marcel Holtmann333140b2008-07-14 20:13:48 +02001367 case HCI_OP_READ_SSP_MODE:
1368 hci_cc_read_ssp_mode(hdev, skb);
1369 break;
1370
1371 case HCI_OP_WRITE_SSP_MODE:
1372 hci_cc_write_ssp_mode(hdev, skb);
1373 break;
1374
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001375 case HCI_OP_READ_LOCAL_VERSION:
1376 hci_cc_read_local_version(hdev, skb);
1377 break;
1378
1379 case HCI_OP_READ_LOCAL_COMMANDS:
1380 hci_cc_read_local_commands(hdev, skb);
1381 break;
1382
1383 case HCI_OP_READ_LOCAL_FEATURES:
1384 hci_cc_read_local_features(hdev, skb);
1385 break;
1386
1387 case HCI_OP_READ_BUFFER_SIZE:
1388 hci_cc_read_buffer_size(hdev, skb);
1389 break;
1390
1391 case HCI_OP_READ_BD_ADDR:
1392 hci_cc_read_bd_addr(hdev, skb);
1393 break;
1394
Johan Hedberg23bb5762010-12-21 23:01:27 +02001395 case HCI_OP_WRITE_CA_TIMEOUT:
1396 hci_cc_write_ca_timeout(hdev, skb);
1397 break;
1398
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001399 default:
1400 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1401 break;
1402 }
1403
1404 if (ev->ncmd) {
1405 atomic_set(&hdev->cmd_cnt, 1);
1406 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001407 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001408 }
1409}
1410
1411static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1412{
1413 struct hci_ev_cmd_status *ev = (void *) skb->data;
1414 __u16 opcode;
1415
1416 skb_pull(skb, sizeof(*ev));
1417
1418 opcode = __le16_to_cpu(ev->opcode);
1419
1420 switch (opcode) {
1421 case HCI_OP_INQUIRY:
1422 hci_cs_inquiry(hdev, ev->status);
1423 break;
1424
1425 case HCI_OP_CREATE_CONN:
1426 hci_cs_create_conn(hdev, ev->status);
1427 break;
1428
1429 case HCI_OP_ADD_SCO:
1430 hci_cs_add_sco(hdev, ev->status);
1431 break;
1432
Marcel Holtmannf8558552008-07-14 20:13:49 +02001433 case HCI_OP_AUTH_REQUESTED:
1434 hci_cs_auth_requested(hdev, ev->status);
1435 break;
1436
1437 case HCI_OP_SET_CONN_ENCRYPT:
1438 hci_cs_set_conn_encrypt(hdev, ev->status);
1439 break;
1440
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001441 case HCI_OP_REMOTE_NAME_REQ:
1442 hci_cs_remote_name_req(hdev, ev->status);
1443 break;
1444
Marcel Holtmann769be972008-07-14 20:13:49 +02001445 case HCI_OP_READ_REMOTE_FEATURES:
1446 hci_cs_read_remote_features(hdev, ev->status);
1447 break;
1448
1449 case HCI_OP_READ_REMOTE_EXT_FEATURES:
1450 hci_cs_read_remote_ext_features(hdev, ev->status);
1451 break;
1452
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001453 case HCI_OP_SETUP_SYNC_CONN:
1454 hci_cs_setup_sync_conn(hdev, ev->status);
1455 break;
1456
1457 case HCI_OP_SNIFF_MODE:
1458 hci_cs_sniff_mode(hdev, ev->status);
1459 break;
1460
1461 case HCI_OP_EXIT_SNIFF_MODE:
1462 hci_cs_exit_sniff_mode(hdev, ev->status);
1463 break;
1464
1465 default:
1466 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1467 break;
1468 }
1469
1470 if (ev->ncmd) {
1471 atomic_set(&hdev->cmd_cnt, 1);
1472 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001473 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001474 }
1475}
1476
1477static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1478{
1479 struct hci_ev_role_change *ev = (void *) skb->data;
1480 struct hci_conn *conn;
1481
1482 BT_DBG("%s status %d", hdev->name, ev->status);
1483
1484 hci_dev_lock(hdev);
1485
1486 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1487 if (conn) {
1488 if (!ev->status) {
1489 if (ev->role)
1490 conn->link_mode &= ~HCI_LM_MASTER;
1491 else
1492 conn->link_mode |= HCI_LM_MASTER;
1493 }
1494
1495 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
1496
1497 hci_role_switch_cfm(conn, ev->status, ev->role);
1498 }
1499
1500 hci_dev_unlock(hdev);
1501}
1502
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
1504{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001505 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001506 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507 int i;
1508
1509 skb_pull(skb, sizeof(*ev));
1510
1511 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
1512
1513 if (skb->len < ev->num_hndl * 4) {
1514 BT_DBG("%s bad parameters", hdev->name);
1515 return;
1516 }
1517
1518 tasklet_disable(&hdev->tx_task);
1519
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001520 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521 struct hci_conn *conn;
1522 __u16 handle, count;
1523
Harvey Harrison83985312008-05-02 16:25:46 -07001524 handle = get_unaligned_le16(ptr++);
1525 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526
1527 conn = hci_conn_hash_lookup_handle(hdev, handle);
1528 if (conn) {
1529 conn->sent -= count;
1530
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001531 if (conn->type == ACL_LINK) {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001532 hdev->acl_cnt += count;
1533 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 hdev->acl_cnt = hdev->acl_pkts;
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001535 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001536 hdev->sco_cnt += count;
1537 if (hdev->sco_cnt > hdev->sco_pkts)
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001538 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 }
1540 }
1541 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001542
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001543 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544
1545 tasklet_enable(&hdev->tx_task);
1546}
1547
Marcel Holtmann04837f62006-07-03 10:02:33 +02001548static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001550 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001551 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552
1553 BT_DBG("%s status %d", hdev->name, ev->status);
1554
1555 hci_dev_lock(hdev);
1556
Marcel Holtmann04837f62006-07-03 10:02:33 +02001557 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1558 if (conn) {
1559 conn->mode = ev->mode;
1560 conn->interval = __le16_to_cpu(ev->interval);
1561
1562 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
1563 if (conn->mode == HCI_CM_ACTIVE)
1564 conn->power_save = 1;
1565 else
1566 conn->power_save = 0;
1567 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001568
1569 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1570 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02001571 }
1572
1573 hci_dev_unlock(hdev);
1574}
1575
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1577{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001578 struct hci_ev_pin_code_req *ev = (void *) skb->data;
1579 struct hci_conn *conn;
1580
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001581 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001582
1583 hci_dev_lock(hdev);
1584
1585 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Marcel Holtmann3d7a9d12009-05-09 12:09:21 -07001586 if (conn && conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001587 hci_conn_hold(conn);
1588 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1589 hci_conn_put(conn);
1590 }
1591
1592 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593}
1594
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1596{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001597 BT_DBG("%s", hdev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598}
1599
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
1601{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001602 struct hci_ev_link_key_notify *ev = (void *) skb->data;
1603 struct hci_conn *conn;
1604
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001605 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001606
1607 hci_dev_lock(hdev);
1608
1609 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1610 if (conn) {
1611 hci_conn_hold(conn);
1612 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1613 hci_conn_put(conn);
1614 }
1615
1616 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617}
1618
Marcel Holtmann04837f62006-07-03 10:02:33 +02001619static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
1620{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001621 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001622 struct hci_conn *conn;
1623
1624 BT_DBG("%s status %d", hdev->name, ev->status);
1625
1626 hci_dev_lock(hdev);
1627
1628 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 if (conn && !ev->status) {
1630 struct inquiry_entry *ie;
1631
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001632 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
1633 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 ie->data.clock_offset = ev->clock_offset;
1635 ie->timestamp = jiffies;
1636 }
1637 }
1638
1639 hci_dev_unlock(hdev);
1640}
1641
Marcel Holtmanna8746412008-07-14 20:13:46 +02001642static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1643{
1644 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
1645 struct hci_conn *conn;
1646
1647 BT_DBG("%s status %d", hdev->name, ev->status);
1648
1649 hci_dev_lock(hdev);
1650
1651 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1652 if (conn && !ev->status)
1653 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
1654
1655 hci_dev_unlock(hdev);
1656}
1657
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001658static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
1659{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001660 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001661 struct inquiry_entry *ie;
1662
1663 BT_DBG("%s", hdev->name);
1664
1665 hci_dev_lock(hdev);
1666
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001667 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1668 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001669 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
1670 ie->timestamp = jiffies;
1671 }
1672
1673 hci_dev_unlock(hdev);
1674}
1675
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001676static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
1677{
1678 struct inquiry_data data;
1679 int num_rsp = *((__u8 *) skb->data);
1680
1681 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1682
1683 if (!num_rsp)
1684 return;
1685
1686 hci_dev_lock(hdev);
1687
1688 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
1689 struct inquiry_info_with_rssi_and_pscan_mode *info = (void *) (skb->data + 1);
1690
1691 for (; num_rsp; num_rsp--) {
1692 bacpy(&data.bdaddr, &info->bdaddr);
1693 data.pscan_rep_mode = info->pscan_rep_mode;
1694 data.pscan_period_mode = info->pscan_period_mode;
1695 data.pscan_mode = info->pscan_mode;
1696 memcpy(data.dev_class, info->dev_class, 3);
1697 data.clock_offset = info->clock_offset;
1698 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001699 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001700 info++;
1701 hci_inquiry_cache_update(hdev, &data);
1702 }
1703 } else {
1704 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
1705
1706 for (; num_rsp; num_rsp--) {
1707 bacpy(&data.bdaddr, &info->bdaddr);
1708 data.pscan_rep_mode = info->pscan_rep_mode;
1709 data.pscan_period_mode = info->pscan_period_mode;
1710 data.pscan_mode = 0x00;
1711 memcpy(data.dev_class, info->dev_class, 3);
1712 data.clock_offset = info->clock_offset;
1713 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001714 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001715 info++;
1716 hci_inquiry_cache_update(hdev, &data);
1717 }
1718 }
1719
1720 hci_dev_unlock(hdev);
1721}
1722
1723static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1724{
Marcel Holtmann41a96212008-07-14 20:13:48 +02001725 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
1726 struct hci_conn *conn;
1727
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001728 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02001729
Marcel Holtmann41a96212008-07-14 20:13:48 +02001730 hci_dev_lock(hdev);
1731
1732 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001733 if (!conn)
1734 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001735
Johan Hedbergccd556f2010-11-10 17:11:51 +02001736 if (!ev->status && ev->page == 0x01) {
1737 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001738
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001739 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
1740 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02001741 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02001742
Johan Hedbergccd556f2010-11-10 17:11:51 +02001743 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02001744 }
1745
Johan Hedbergccd556f2010-11-10 17:11:51 +02001746 if (conn->state != BT_CONFIG)
1747 goto unlock;
1748
Johan Hedberg127178d2010-11-18 22:22:29 +02001749 if (!ev->status) {
1750 struct hci_cp_remote_name_req cp;
1751 memset(&cp, 0, sizeof(cp));
1752 bacpy(&cp.bdaddr, &conn->dst);
1753 cp.pscan_rep_mode = 0x02;
1754 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1755 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001756
Johan Hedberg127178d2010-11-18 22:22:29 +02001757 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001758 conn->state = BT_CONNECTED;
1759 hci_proto_connect_cfm(conn, ev->status);
1760 hci_conn_put(conn);
1761 }
1762
1763unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02001764 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001765}
1766
1767static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1768{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001769 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
1770 struct hci_conn *conn;
1771
1772 BT_DBG("%s status %d", hdev->name, ev->status);
1773
1774 hci_dev_lock(hdev);
1775
1776 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02001777 if (!conn) {
1778 if (ev->link_type == ESCO_LINK)
1779 goto unlock;
1780
1781 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1782 if (!conn)
1783 goto unlock;
1784
1785 conn->type = SCO_LINK;
1786 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001787
Marcel Holtmann732547f2009-04-19 19:14:14 +02001788 switch (ev->status) {
1789 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001790 conn->handle = __le16_to_cpu(ev->handle);
1791 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001792
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001793 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001794 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02001795 break;
1796
Stephen Coe705e5712010-02-16 11:29:44 -05001797 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02001798 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08001799 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02001800 case 0x1f: /* Unspecified error */
1801 if (conn->out && conn->attempt < 2) {
1802 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
1803 (hdev->esco_type & EDR_ESCO_MASK);
1804 hci_setup_sync(conn, conn->link->handle);
1805 goto unlock;
1806 }
1807 /* fall through */
1808
1809 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001810 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02001811 break;
1812 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001813
1814 hci_proto_connect_cfm(conn, ev->status);
1815 if (ev->status)
1816 hci_conn_del(conn);
1817
1818unlock:
1819 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001820}
1821
1822static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
1823{
1824 BT_DBG("%s", hdev->name);
1825}
1826
Marcel Holtmann04837f62006-07-03 10:02:33 +02001827static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
1828{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001829 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001830 struct hci_conn *conn;
1831
1832 BT_DBG("%s status %d", hdev->name, ev->status);
1833
1834 hci_dev_lock(hdev);
1835
1836 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1837 if (conn) {
1838 }
1839
1840 hci_dev_unlock(hdev);
1841}
1842
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001843static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1844{
1845 struct inquiry_data data;
1846 struct extended_inquiry_info *info = (void *) (skb->data + 1);
1847 int num_rsp = *((__u8 *) skb->data);
1848
1849 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1850
1851 if (!num_rsp)
1852 return;
1853
1854 hci_dev_lock(hdev);
1855
1856 for (; num_rsp; num_rsp--) {
1857 bacpy(&data.bdaddr, &info->bdaddr);
1858 data.pscan_rep_mode = info->pscan_rep_mode;
1859 data.pscan_period_mode = info->pscan_period_mode;
1860 data.pscan_mode = 0x00;
1861 memcpy(data.dev_class, info->dev_class, 3);
1862 data.clock_offset = info->clock_offset;
1863 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001864 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001865 info++;
1866 hci_inquiry_cache_update(hdev, &data);
1867 }
1868
1869 hci_dev_unlock(hdev);
1870}
1871
Marcel Holtmann04936842008-07-14 20:13:48 +02001872static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1873{
1874 struct hci_ev_io_capa_request *ev = (void *) skb->data;
1875 struct hci_conn *conn;
1876
1877 BT_DBG("%s", hdev->name);
1878
1879 hci_dev_lock(hdev);
1880
1881 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1882 if (conn)
1883 hci_conn_hold(conn);
1884
1885 hci_dev_unlock(hdev);
1886}
1887
1888static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1889{
1890 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
1891 struct hci_conn *conn;
1892
1893 BT_DBG("%s", hdev->name);
1894
1895 hci_dev_lock(hdev);
1896
1897 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1898 if (conn)
1899 hci_conn_put(conn);
1900
1901 hci_dev_unlock(hdev);
1902}
1903
Marcel Holtmann41a96212008-07-14 20:13:48 +02001904static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1905{
1906 struct hci_ev_remote_host_features *ev = (void *) skb->data;
1907 struct inquiry_entry *ie;
1908
1909 BT_DBG("%s", hdev->name);
1910
1911 hci_dev_lock(hdev);
1912
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001913 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1914 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02001915 ie->data.ssp_mode = (ev->features[0] & 0x01);
1916
1917 hci_dev_unlock(hdev);
1918}
1919
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
1921{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001922 struct hci_event_hdr *hdr = (void *) skb->data;
1923 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924
1925 skb_pull(skb, HCI_EVENT_HDR_SIZE);
1926
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001927 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928 case HCI_EV_INQUIRY_COMPLETE:
1929 hci_inquiry_complete_evt(hdev, skb);
1930 break;
1931
1932 case HCI_EV_INQUIRY_RESULT:
1933 hci_inquiry_result_evt(hdev, skb);
1934 break;
1935
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001936 case HCI_EV_CONN_COMPLETE:
1937 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02001938 break;
1939
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940 case HCI_EV_CONN_REQUEST:
1941 hci_conn_request_evt(hdev, skb);
1942 break;
1943
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 case HCI_EV_DISCONN_COMPLETE:
1945 hci_disconn_complete_evt(hdev, skb);
1946 break;
1947
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948 case HCI_EV_AUTH_COMPLETE:
1949 hci_auth_complete_evt(hdev, skb);
1950 break;
1951
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001952 case HCI_EV_REMOTE_NAME:
1953 hci_remote_name_evt(hdev, skb);
1954 break;
1955
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956 case HCI_EV_ENCRYPT_CHANGE:
1957 hci_encrypt_change_evt(hdev, skb);
1958 break;
1959
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001960 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
1961 hci_change_link_key_complete_evt(hdev, skb);
1962 break;
1963
1964 case HCI_EV_REMOTE_FEATURES:
1965 hci_remote_features_evt(hdev, skb);
1966 break;
1967
1968 case HCI_EV_REMOTE_VERSION:
1969 hci_remote_version_evt(hdev, skb);
1970 break;
1971
1972 case HCI_EV_QOS_SETUP_COMPLETE:
1973 hci_qos_setup_complete_evt(hdev, skb);
1974 break;
1975
1976 case HCI_EV_CMD_COMPLETE:
1977 hci_cmd_complete_evt(hdev, skb);
1978 break;
1979
1980 case HCI_EV_CMD_STATUS:
1981 hci_cmd_status_evt(hdev, skb);
1982 break;
1983
1984 case HCI_EV_ROLE_CHANGE:
1985 hci_role_change_evt(hdev, skb);
1986 break;
1987
1988 case HCI_EV_NUM_COMP_PKTS:
1989 hci_num_comp_pkts_evt(hdev, skb);
1990 break;
1991
1992 case HCI_EV_MODE_CHANGE:
1993 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001994 break;
1995
1996 case HCI_EV_PIN_CODE_REQ:
1997 hci_pin_code_request_evt(hdev, skb);
1998 break;
1999
2000 case HCI_EV_LINK_KEY_REQ:
2001 hci_link_key_request_evt(hdev, skb);
2002 break;
2003
2004 case HCI_EV_LINK_KEY_NOTIFY:
2005 hci_link_key_notify_evt(hdev, skb);
2006 break;
2007
2008 case HCI_EV_CLOCK_OFFSET:
2009 hci_clock_offset_evt(hdev, skb);
2010 break;
2011
Marcel Holtmanna8746412008-07-14 20:13:46 +02002012 case HCI_EV_PKT_TYPE_CHANGE:
2013 hci_pkt_type_change_evt(hdev, skb);
2014 break;
2015
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002016 case HCI_EV_PSCAN_REP_MODE:
2017 hci_pscan_rep_mode_evt(hdev, skb);
2018 break;
2019
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002020 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
2021 hci_inquiry_result_with_rssi_evt(hdev, skb);
2022 break;
2023
2024 case HCI_EV_REMOTE_EXT_FEATURES:
2025 hci_remote_ext_features_evt(hdev, skb);
2026 break;
2027
2028 case HCI_EV_SYNC_CONN_COMPLETE:
2029 hci_sync_conn_complete_evt(hdev, skb);
2030 break;
2031
2032 case HCI_EV_SYNC_CONN_CHANGED:
2033 hci_sync_conn_changed_evt(hdev, skb);
2034 break;
2035
Marcel Holtmann04837f62006-07-03 10:02:33 +02002036 case HCI_EV_SNIFF_SUBRATE:
2037 hci_sniff_subrate_evt(hdev, skb);
2038 break;
2039
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002040 case HCI_EV_EXTENDED_INQUIRY_RESULT:
2041 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002042 break;
2043
Marcel Holtmann04936842008-07-14 20:13:48 +02002044 case HCI_EV_IO_CAPA_REQUEST:
2045 hci_io_capa_request_evt(hdev, skb);
2046 break;
2047
2048 case HCI_EV_SIMPLE_PAIR_COMPLETE:
2049 hci_simple_pair_complete_evt(hdev, skb);
2050 break;
2051
Marcel Holtmann41a96212008-07-14 20:13:48 +02002052 case HCI_EV_REMOTE_HOST_FEATURES:
2053 hci_remote_host_features_evt(hdev, skb);
2054 break;
2055
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002056 default:
2057 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002058 break;
2059 }
2060
2061 kfree_skb(skb);
2062 hdev->stat.evt_rx++;
2063}
2064
2065/* Generate internal stack event */
2066void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
2067{
2068 struct hci_event_hdr *hdr;
2069 struct hci_ev_stack_internal *ev;
2070 struct sk_buff *skb;
2071
2072 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
2073 if (!skb)
2074 return;
2075
2076 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
2077 hdr->evt = HCI_EV_STACK_INTERNAL;
2078 hdr->plen = sizeof(*ev) + dlen;
2079
2080 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
2081 ev->type = type;
2082 memcpy(ev->data, data, dlen);
2083
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002084 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07002085 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002086
Marcel Holtmann0d48d932005-08-09 20:30:28 -07002087 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02002089 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090 kfree_skb(skb);
2091}