]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - net/bluetooth/mgmt.c
Bluetooth: Validate data size before accessing mgmt commands
[mirror_ubuntu-artful-kernel.git] / net / bluetooth / mgmt.c
CommitLineData
0381101f
JH
1/*
2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2010 Nokia Corporation
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation;
8
9 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20 SOFTWARE IS DISCLAIMED.
21*/
22
23/* Bluetooth HCI Management interface */
24
72359753 25#include <linux/uaccess.h>
0381101f
JH
26#include <asm/unaligned.h>
27
28#include <net/bluetooth/bluetooth.h>
29#include <net/bluetooth/hci_core.h>
30#include <net/bluetooth/mgmt.h>
31
02d98129
JH
32#define MGMT_VERSION 0
33#define MGMT_REVISION 1
34
eec8d2bc
JH
35struct pending_cmd {
36 struct list_head list;
37 __u16 opcode;
38 int index;
39 void *cmd;
40 struct sock *sk;
e9a416b5 41 void *user_data;
eec8d2bc
JH
42};
43
44LIST_HEAD(cmd_list);
45
4e51eae9 46static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
f7b64e69
JH
47{
48 struct sk_buff *skb;
49 struct mgmt_hdr *hdr;
50 struct mgmt_ev_cmd_status *ev;
51
52 BT_DBG("sock %p", sk);
53
54 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC);
55 if (!skb)
56 return -ENOMEM;
57
58 hdr = (void *) skb_put(skb, sizeof(*hdr));
59
60 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS);
4e51eae9 61 hdr->index = cpu_to_le16(index);
f7b64e69
JH
62 hdr->len = cpu_to_le16(sizeof(*ev));
63
64 ev = (void *) skb_put(skb, sizeof(*ev));
65 ev->status = status;
66 put_unaligned_le16(cmd, &ev->opcode);
67
68 if (sock_queue_rcv_skb(sk, skb) < 0)
69 kfree_skb(skb);
70
71 return 0;
72}
73
4e51eae9
SJ
74static int cmd_complete(struct sock *sk, u16 index, u16 cmd, void *rp,
75 size_t rp_len)
02d98129
JH
76{
77 struct sk_buff *skb;
78 struct mgmt_hdr *hdr;
79 struct mgmt_ev_cmd_complete *ev;
02d98129
JH
80
81 BT_DBG("sock %p", sk);
82
a38528f1 83 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_ATOMIC);
02d98129
JH
84 if (!skb)
85 return -ENOMEM;
86
87 hdr = (void *) skb_put(skb, sizeof(*hdr));
02d98129 88
a38528f1 89 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
4e51eae9 90 hdr->index = cpu_to_le16(index);
a38528f1 91 hdr->len = cpu_to_le16(sizeof(*ev) + rp_len);
02d98129 92
a38528f1
JH
93 ev = (void *) skb_put(skb, sizeof(*ev) + rp_len);
94 put_unaligned_le16(cmd, &ev->opcode);
95 memcpy(ev->data, rp, rp_len);
02d98129
JH
96
97 if (sock_queue_rcv_skb(sk, skb) < 0)
98 kfree_skb(skb);
99
100 return 0;
101}
102
a38528f1
JH
103static int read_version(struct sock *sk)
104{
105 struct mgmt_rp_read_version rp;
106
107 BT_DBG("sock %p", sk);
108
109 rp.version = MGMT_VERSION;
110 put_unaligned_le16(MGMT_REVISION, &rp.revision);
111
4e51eae9
SJ
112 return cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_VERSION, &rp,
113 sizeof(rp));
a38528f1
JH
114}
115
faba42eb
JH
116static int read_index_list(struct sock *sk)
117{
faba42eb
JH
118 struct mgmt_rp_read_index_list *rp;
119 struct list_head *p;
a38528f1 120 size_t rp_len;
faba42eb 121 u16 count;
a38528f1 122 int i, err;
faba42eb
JH
123
124 BT_DBG("sock %p", sk);
125
126 read_lock(&hci_dev_list_lock);
127
128 count = 0;
129 list_for_each(p, &hci_dev_list) {
130 count++;
131 }
132
a38528f1
JH
133 rp_len = sizeof(*rp) + (2 * count);
134 rp = kmalloc(rp_len, GFP_ATOMIC);
135 if (!rp) {
b2c60d42 136 read_unlock(&hci_dev_list_lock);
faba42eb 137 return -ENOMEM;
b2c60d42 138 }
faba42eb 139
faba42eb
JH
140 put_unaligned_le16(count, &rp->num_controllers);
141
142 i = 0;
143 list_for_each(p, &hci_dev_list) {
144 struct hci_dev *d = list_entry(p, struct hci_dev, list);
ab81cbf9
JH
145
146 hci_del_off_timer(d);
147
ebc99feb
JH
148 set_bit(HCI_MGMT, &d->flags);
149
ab81cbf9
JH
150 if (test_bit(HCI_SETUP, &d->flags))
151 continue;
152
faba42eb
JH
153 put_unaligned_le16(d->id, &rp->index[i++]);
154 BT_DBG("Added hci%u", d->id);
155 }
156
157 read_unlock(&hci_dev_list_lock);
158
4e51eae9
SJ
159 err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, rp,
160 rp_len);
faba42eb 161
a38528f1
JH
162 kfree(rp);
163
164 return err;
faba42eb
JH
165}
166
4e51eae9 167static int read_controller_info(struct sock *sk, u16 index)
0381101f 168{
a38528f1 169 struct mgmt_rp_read_info rp;
f7b64e69 170 struct hci_dev *hdev;
0381101f 171
4e51eae9 172 BT_DBG("sock %p hci%u", sk, index);
f7b64e69 173
4e51eae9 174 hdev = hci_dev_get(index);
a38528f1 175 if (!hdev)
4e51eae9 176 return cmd_status(sk, index, MGMT_OP_READ_INFO, ENODEV);
f7b64e69 177
ab81cbf9
JH
178 hci_del_off_timer(hdev);
179
f7b64e69
JH
180 hci_dev_lock_bh(hdev);
181
ebc99feb
JH
182 set_bit(HCI_MGMT, &hdev->flags);
183
a38528f1 184 rp.type = hdev->dev_type;
f7b64e69 185
a38528f1
JH
186 rp.powered = test_bit(HCI_UP, &hdev->flags);
187 rp.connectable = test_bit(HCI_PSCAN, &hdev->flags);
188 rp.discoverable = test_bit(HCI_ISCAN, &hdev->flags);
189 rp.pairable = test_bit(HCI_PSCAN, &hdev->flags);
f7b64e69
JH
190
191 if (test_bit(HCI_AUTH, &hdev->flags))
a38528f1 192 rp.sec_mode = 3;
f7b64e69 193 else if (hdev->ssp_mode > 0)
a38528f1 194 rp.sec_mode = 4;
f7b64e69 195 else
a38528f1 196 rp.sec_mode = 2;
f7b64e69 197
a38528f1
JH
198 bacpy(&rp.bdaddr, &hdev->bdaddr);
199 memcpy(rp.features, hdev->features, 8);
200 memcpy(rp.dev_class, hdev->dev_class, 3);
201 put_unaligned_le16(hdev->manufacturer, &rp.manufacturer);
202 rp.hci_ver = hdev->hci_ver;
203 put_unaligned_le16(hdev->hci_rev, &rp.hci_rev);
f7b64e69
JH
204
205 hci_dev_unlock_bh(hdev);
206 hci_dev_put(hdev);
0381101f 207
4e51eae9 208 return cmd_complete(sk, index, MGMT_OP_READ_INFO, &rp, sizeof(rp));
0381101f
JH
209}
210
eec8d2bc
JH
211static void mgmt_pending_free(struct pending_cmd *cmd)
212{
213 sock_put(cmd->sk);
214 kfree(cmd->cmd);
215 kfree(cmd);
216}
217
366a0336
JH
218static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
219 u16 index, void *data, u16 len)
eec8d2bc
JH
220{
221 struct pending_cmd *cmd;
222
223 cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
224 if (!cmd)
366a0336 225 return NULL;
eec8d2bc
JH
226
227 cmd->opcode = opcode;
228 cmd->index = index;
229
230 cmd->cmd = kmalloc(len, GFP_ATOMIC);
231 if (!cmd->cmd) {
232 kfree(cmd);
366a0336 233 return NULL;
eec8d2bc
JH
234 }
235
236 memcpy(cmd->cmd, data, len);
237
238 cmd->sk = sk;
239 sock_hold(sk);
240
241 list_add(&cmd->list, &cmd_list);
242
366a0336 243 return cmd;
eec8d2bc
JH
244}
245
246static void mgmt_pending_foreach(u16 opcode, int index,
247 void (*cb)(struct pending_cmd *cmd, void *data),
248 void *data)
249{
250 struct list_head *p, *n;
251
252 list_for_each_safe(p, n, &cmd_list) {
253 struct pending_cmd *cmd;
254
255 cmd = list_entry(p, struct pending_cmd, list);
256
257 if (cmd->opcode != opcode)
258 continue;
259
260 if (index >= 0 && cmd->index != index)
261 continue;
262
263 cb(cmd, data);
264 }
265}
266
267static struct pending_cmd *mgmt_pending_find(u16 opcode, int index)
268{
269 struct list_head *p;
270
271 list_for_each(p, &cmd_list) {
272 struct pending_cmd *cmd;
273
274 cmd = list_entry(p, struct pending_cmd, list);
275
276 if (cmd->opcode != opcode)
277 continue;
278
279 if (index >= 0 && cmd->index != index)
280 continue;
281
282 return cmd;
283 }
284
285 return NULL;
286}
287
a664b5bc 288static void mgmt_pending_remove(struct pending_cmd *cmd)
73f22f62 289{
73f22f62
JH
290 list_del(&cmd->list);
291 mgmt_pending_free(cmd);
292}
293
4e51eae9 294static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len)
eec8d2bc 295{
72a734ec 296 struct mgmt_mode *cp;
eec8d2bc 297 struct hci_dev *hdev;
366a0336 298 struct pending_cmd *cmd;
366a0336 299 int err, up;
eec8d2bc
JH
300
301 cp = (void *) data;
eec8d2bc 302
4e51eae9 303 BT_DBG("request for hci%u", index);
eec8d2bc 304
bdce7baf
SJ
305 if (len != sizeof(*cp))
306 return cmd_status(sk, index, MGMT_OP_SET_POWERED, EINVAL);
307
4e51eae9 308 hdev = hci_dev_get(index);
eec8d2bc 309 if (!hdev)
4e51eae9 310 return cmd_status(sk, index, MGMT_OP_SET_POWERED, ENODEV);
eec8d2bc
JH
311
312 hci_dev_lock_bh(hdev);
313
314 up = test_bit(HCI_UP, &hdev->flags);
72a734ec 315 if ((cp->val && up) || (!cp->val && !up)) {
4e51eae9 316 err = cmd_status(sk, index, MGMT_OP_SET_POWERED, EALREADY);
eec8d2bc
JH
317 goto failed;
318 }
319
4e51eae9
SJ
320 if (mgmt_pending_find(MGMT_OP_SET_POWERED, index)) {
321 err = cmd_status(sk, index, MGMT_OP_SET_POWERED, EBUSY);
eec8d2bc
JH
322 goto failed;
323 }
324
4e51eae9 325 cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, index, data, len);
366a0336
JH
326 if (!cmd) {
327 err = -ENOMEM;
eec8d2bc 328 goto failed;
366a0336 329 }
eec8d2bc 330
72a734ec 331 if (cp->val)
eec8d2bc
JH
332 queue_work(hdev->workqueue, &hdev->power_on);
333 else
334 queue_work(hdev->workqueue, &hdev->power_off);
335
366a0336 336 err = 0;
eec8d2bc
JH
337
338failed:
339 hci_dev_unlock_bh(hdev);
340 hci_dev_put(hdev);
366a0336 341 return err;
eec8d2bc
JH
342}
343
4e51eae9
SJ
344static int set_discoverable(struct sock *sk, u16 index, unsigned char *data,
345 u16 len)
73f22f62 346{
72a734ec 347 struct mgmt_mode *cp;
73f22f62 348 struct hci_dev *hdev;
366a0336 349 struct pending_cmd *cmd;
73f22f62
JH
350 u8 scan;
351 int err;
352
353 cp = (void *) data;
73f22f62 354
4e51eae9 355 BT_DBG("request for hci%u", index);
73f22f62 356
bdce7baf
SJ
357 if (len != sizeof(*cp))
358 return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, EINVAL);
359
4e51eae9 360 hdev = hci_dev_get(index);
73f22f62 361 if (!hdev)
4e51eae9 362 return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENODEV);
73f22f62
JH
363
364 hci_dev_lock_bh(hdev);
365
366 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9 367 err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENETDOWN);
73f22f62
JH
368 goto failed;
369 }
370
4e51eae9
SJ
371 if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, index) ||
372 mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, index)) {
373 err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, EBUSY);
73f22f62
JH
374 goto failed;
375 }
376
72a734ec 377 if (cp->val == test_bit(HCI_ISCAN, &hdev->flags) &&
73f22f62 378 test_bit(HCI_PSCAN, &hdev->flags)) {
4e51eae9 379 err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, EALREADY);
73f22f62
JH
380 goto failed;
381 }
382
4e51eae9 383 cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, index, data, len);
366a0336
JH
384 if (!cmd) {
385 err = -ENOMEM;
73f22f62 386 goto failed;
366a0336 387 }
73f22f62
JH
388
389 scan = SCAN_PAGE;
390
72a734ec 391 if (cp->val)
73f22f62
JH
392 scan |= SCAN_INQUIRY;
393
394 err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
395 if (err < 0)
a664b5bc 396 mgmt_pending_remove(cmd);
73f22f62
JH
397
398failed:
399 hci_dev_unlock_bh(hdev);
400 hci_dev_put(hdev);
401
402 return err;
403}
404
4e51eae9
SJ
405static int set_connectable(struct sock *sk, u16 index, unsigned char *data,
406 u16 len)
9fbcbb45 407{
72a734ec 408 struct mgmt_mode *cp;
9fbcbb45 409 struct hci_dev *hdev;
366a0336 410 struct pending_cmd *cmd;
9fbcbb45
JH
411 u8 scan;
412 int err;
413
414 cp = (void *) data;
9fbcbb45 415
4e51eae9 416 BT_DBG("request for hci%u", index);
9fbcbb45 417
bdce7baf
SJ
418 if (len != sizeof(*cp))
419 return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EINVAL);
420
4e51eae9 421 hdev = hci_dev_get(index);
9fbcbb45 422 if (!hdev)
4e51eae9 423 return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENODEV);
9fbcbb45
JH
424
425 hci_dev_lock_bh(hdev);
426
427 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9 428 err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENETDOWN);
9fbcbb45
JH
429 goto failed;
430 }
431
4e51eae9
SJ
432 if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, index) ||
433 mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, index)) {
434 err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EBUSY);
9fbcbb45
JH
435 goto failed;
436 }
437
72a734ec 438 if (cp->val == test_bit(HCI_PSCAN, &hdev->flags)) {
4e51eae9 439 err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EALREADY);
9fbcbb45
JH
440 goto failed;
441 }
442
4e51eae9 443 cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, index, data, len);
366a0336
JH
444 if (!cmd) {
445 err = -ENOMEM;
9fbcbb45 446 goto failed;
366a0336 447 }
9fbcbb45 448
72a734ec 449 if (cp->val)
9fbcbb45
JH
450 scan = SCAN_PAGE;
451 else
452 scan = 0;
453
454 err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
455 if (err < 0)
a664b5bc 456 mgmt_pending_remove(cmd);
9fbcbb45
JH
457
458failed:
459 hci_dev_unlock_bh(hdev);
460 hci_dev_put(hdev);
461
462 return err;
463}
464
4e51eae9
SJ
465static int mgmt_event(u16 event, u16 index, void *data, u16 data_len,
466 struct sock *skip_sk)
c542a06c
JH
467{
468 struct sk_buff *skb;
469 struct mgmt_hdr *hdr;
470
471 skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC);
472 if (!skb)
473 return -ENOMEM;
474
475 bt_cb(skb)->channel = HCI_CHANNEL_CONTROL;
476
477 hdr = (void *) skb_put(skb, sizeof(*hdr));
478 hdr->opcode = cpu_to_le16(event);
4e51eae9 479 hdr->index = cpu_to_le16(index);
c542a06c
JH
480 hdr->len = cpu_to_le16(data_len);
481
4e51eae9
SJ
482 if (data)
483 memcpy(skb_put(skb, data_len), data, data_len);
c542a06c
JH
484
485 hci_send_to_sock(NULL, skb, skip_sk);
486 kfree_skb(skb);
487
488 return 0;
489}
490
053f0211
JH
491static int send_mode_rsp(struct sock *sk, u16 opcode, u16 index, u8 val)
492{
a38528f1 493 struct mgmt_mode rp;
053f0211 494
a38528f1 495 rp.val = val;
053f0211 496
4e51eae9 497 return cmd_complete(sk, index, opcode, &rp, sizeof(rp));
053f0211
JH
498}
499
4e51eae9
SJ
500static int set_pairable(struct sock *sk, u16 index, unsigned char *data,
501 u16 len)
c542a06c
JH
502{
503 struct mgmt_mode *cp, ev;
504 struct hci_dev *hdev;
c542a06c
JH
505 int err;
506
507 cp = (void *) data;
c542a06c 508
4e51eae9 509 BT_DBG("request for hci%u", index);
c542a06c 510
bdce7baf
SJ
511 if (len != sizeof(*cp))
512 return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, EINVAL);
513
4e51eae9 514 hdev = hci_dev_get(index);
c542a06c 515 if (!hdev)
4e51eae9 516 return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, ENODEV);
c542a06c
JH
517
518 hci_dev_lock_bh(hdev);
519
520 if (cp->val)
521 set_bit(HCI_PAIRABLE, &hdev->flags);
522 else
523 clear_bit(HCI_PAIRABLE, &hdev->flags);
524
4e51eae9 525 err = send_mode_rsp(sk, MGMT_OP_SET_PAIRABLE, index, cp->val);
c542a06c
JH
526 if (err < 0)
527 goto failed;
528
c542a06c
JH
529 ev.val = cp->val;
530
4e51eae9 531 err = mgmt_event(MGMT_EV_PAIRABLE, index, &ev, sizeof(ev), sk);
c542a06c
JH
532
533failed:
534 hci_dev_unlock_bh(hdev);
535 hci_dev_put(hdev);
536
537 return err;
538}
539
1aff6f09
JH
540static u8 get_service_classes(struct hci_dev *hdev)
541{
542 struct list_head *p;
543 u8 val = 0;
544
545 list_for_each(p, &hdev->uuids) {
546 struct bt_uuid *uuid = list_entry(p, struct bt_uuid, list);
547
548 val |= uuid->svc_hint;
549 }
550
551 return val;
552}
553
554static int update_class(struct hci_dev *hdev)
555{
556 u8 cod[3];
557
558 BT_DBG("%s", hdev->name);
559
560 if (test_bit(HCI_SERVICE_CACHE, &hdev->flags))
561 return 0;
562
563 cod[0] = hdev->minor_class;
564 cod[1] = hdev->major_class;
565 cod[2] = get_service_classes(hdev);
566
567 if (memcmp(cod, hdev->dev_class, 3) == 0)
568 return 0;
569
570 return hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
571}
572
4e51eae9 573static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
2aeb9a1a
JH
574{
575 struct mgmt_cp_add_uuid *cp;
576 struct hci_dev *hdev;
577 struct bt_uuid *uuid;
2aeb9a1a
JH
578 int err;
579
580 cp = (void *) data;
2aeb9a1a 581
4e51eae9 582 BT_DBG("request for hci%u", index);
2aeb9a1a 583
bdce7baf
SJ
584 if (len != sizeof(*cp))
585 return cmd_status(sk, index, MGMT_OP_ADD_UUID, EINVAL);
586
4e51eae9 587 hdev = hci_dev_get(index);
2aeb9a1a 588 if (!hdev)
4e51eae9 589 return cmd_status(sk, index, MGMT_OP_ADD_UUID, ENODEV);
2aeb9a1a
JH
590
591 hci_dev_lock_bh(hdev);
592
593 uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC);
594 if (!uuid) {
595 err = -ENOMEM;
596 goto failed;
597 }
598
599 memcpy(uuid->uuid, cp->uuid, 16);
1aff6f09 600 uuid->svc_hint = cp->svc_hint;
2aeb9a1a
JH
601
602 list_add(&uuid->list, &hdev->uuids);
603
1aff6f09
JH
604 err = update_class(hdev);
605 if (err < 0)
606 goto failed;
607
4e51eae9 608 err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, NULL, 0);
2aeb9a1a
JH
609
610failed:
611 hci_dev_unlock_bh(hdev);
612 hci_dev_put(hdev);
613
614 return err;
615}
616
4e51eae9 617static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
2aeb9a1a
JH
618{
619 struct list_head *p, *n;
779cb850 620 struct mgmt_cp_remove_uuid *cp;
2aeb9a1a
JH
621 struct hci_dev *hdev;
622 u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2aeb9a1a
JH
623 int err, found;
624
625 cp = (void *) data;
2aeb9a1a 626
4e51eae9 627 BT_DBG("request for hci%u", index);
2aeb9a1a 628
bdce7baf
SJ
629 if (len != sizeof(*cp))
630 return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, EINVAL);
631
4e51eae9 632 hdev = hci_dev_get(index);
2aeb9a1a 633 if (!hdev)
4e51eae9 634 return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENODEV);
2aeb9a1a
JH
635
636 hci_dev_lock_bh(hdev);
637
638 if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) {
639 err = hci_uuids_clear(hdev);
640 goto unlock;
641 }
642
643 found = 0;
644
645 list_for_each_safe(p, n, &hdev->uuids) {
646 struct bt_uuid *match = list_entry(p, struct bt_uuid, list);
647
648 if (memcmp(match->uuid, cp->uuid, 16) != 0)
649 continue;
650
651 list_del(&match->list);
652 found++;
653 }
654
655 if (found == 0) {
4e51eae9 656 err = cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENOENT);
2aeb9a1a
JH
657 goto unlock;
658 }
659
1aff6f09
JH
660 err = update_class(hdev);
661 if (err < 0)
662 goto unlock;
663
4e51eae9 664 err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0);
2aeb9a1a
JH
665
666unlock:
667 hci_dev_unlock_bh(hdev);
668 hci_dev_put(hdev);
669
670 return err;
671}
672
4e51eae9
SJ
673static int set_dev_class(struct sock *sk, u16 index, unsigned char *data,
674 u16 len)
1aff6f09
JH
675{
676 struct hci_dev *hdev;
677 struct mgmt_cp_set_dev_class *cp;
1aff6f09
JH
678 int err;
679
680 cp = (void *) data;
1aff6f09 681
4e51eae9 682 BT_DBG("request for hci%u", index);
1aff6f09 683
bdce7baf
SJ
684 if (len != sizeof(*cp))
685 return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, EINVAL);
686
4e51eae9 687 hdev = hci_dev_get(index);
1aff6f09 688 if (!hdev)
4e51eae9 689 return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, ENODEV);
1aff6f09
JH
690
691 hci_dev_lock_bh(hdev);
692
693 hdev->major_class = cp->major;
694 hdev->minor_class = cp->minor;
695
696 err = update_class(hdev);
697
698 if (err == 0)
4e51eae9 699 err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, NULL, 0);
1aff6f09
JH
700
701 hci_dev_unlock_bh(hdev);
702 hci_dev_put(hdev);
703
704 return err;
705}
706
4e51eae9
SJ
707static int set_service_cache(struct sock *sk, u16 index, unsigned char *data,
708 u16 len)
1aff6f09
JH
709{
710 struct hci_dev *hdev;
711 struct mgmt_cp_set_service_cache *cp;
1aff6f09
JH
712 int err;
713
714 cp = (void *) data;
1aff6f09 715
bdce7baf
SJ
716 if (len != sizeof(*cp))
717 return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE,
718 EINVAL);
719
4e51eae9 720 hdev = hci_dev_get(index);
1aff6f09 721 if (!hdev)
4e51eae9 722 return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, ENODEV);
1aff6f09
JH
723
724 hci_dev_lock_bh(hdev);
725
4e51eae9 726 BT_DBG("hci%u enable %d", index, cp->enable);
1aff6f09
JH
727
728 if (cp->enable) {
729 set_bit(HCI_SERVICE_CACHE, &hdev->flags);
730 err = 0;
731 } else {
732 clear_bit(HCI_SERVICE_CACHE, &hdev->flags);
733 err = update_class(hdev);
734 }
735
736 if (err == 0)
4e51eae9
SJ
737 err = cmd_complete(sk, index, MGMT_OP_SET_SERVICE_CACHE, NULL,
738 0);
1aff6f09
JH
739
740 hci_dev_unlock_bh(hdev);
741 hci_dev_put(hdev);
742
743 return err;
744}
745
4e51eae9 746static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
55ed8ca1
JH
747{
748 struct hci_dev *hdev;
749 struct mgmt_cp_load_keys *cp;
4e51eae9 750 u16 key_count, expected_len;
55ed8ca1
JH
751 int i;
752
753 cp = (void *) data;
bdce7baf
SJ
754
755 if (len < sizeof(*cp))
756 return -EINVAL;
757
55ed8ca1
JH
758 key_count = get_unaligned_le16(&cp->key_count);
759
760 expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info);
761 if (expected_len != len) {
762 BT_ERR("load_keys: expected %u bytes, got %u bytes",
763 len, expected_len);
764 return -EINVAL;
765 }
766
4e51eae9 767 hdev = hci_dev_get(index);
55ed8ca1 768 if (!hdev)
4e51eae9 769 return cmd_status(sk, index, MGMT_OP_LOAD_KEYS, ENODEV);
55ed8ca1 770
4e51eae9 771 BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys,
55ed8ca1
JH
772 key_count);
773
774 hci_dev_lock_bh(hdev);
775
776 hci_link_keys_clear(hdev);
777
778 set_bit(HCI_LINK_KEYS, &hdev->flags);
779
780 if (cp->debug_keys)
781 set_bit(HCI_DEBUG_KEYS, &hdev->flags);
782 else
783 clear_bit(HCI_DEBUG_KEYS, &hdev->flags);
784
785 for (i = 0; i < key_count; i++) {
786 struct mgmt_key_info *key = &cp->keys[i];
787
788 hci_add_link_key(hdev, 0, &key->bdaddr, key->val, key->type,
789 key->pin_len);
790 }
791
792 hci_dev_unlock_bh(hdev);
793 hci_dev_put(hdev);
794
795 return 0;
796}
797
4e51eae9 798static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len)
55ed8ca1
JH
799{
800 struct hci_dev *hdev;
801 struct mgmt_cp_remove_key *cp;
802 struct hci_conn *conn;
55ed8ca1
JH
803 int err;
804
805 cp = (void *) data;
55ed8ca1 806
bdce7baf
SJ
807 if (len != sizeof(*cp))
808 return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, EINVAL);
809
4e51eae9 810 hdev = hci_dev_get(index);
55ed8ca1 811 if (!hdev)
4e51eae9 812 return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, ENODEV);
55ed8ca1
JH
813
814 hci_dev_lock_bh(hdev);
815
816 err = hci_remove_link_key(hdev, &cp->bdaddr);
817 if (err < 0) {
4e51eae9 818 err = cmd_status(sk, index, MGMT_OP_REMOVE_KEY, -err);
55ed8ca1
JH
819 goto unlock;
820 }
821
822 err = 0;
823
824 if (!test_bit(HCI_UP, &hdev->flags) || !cp->disconnect)
825 goto unlock;
826
827 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
828 if (conn) {
829 struct hci_cp_disconnect dc;
830
831 put_unaligned_le16(conn->handle, &dc.handle);
832 dc.reason = 0x13; /* Remote User Terminated Connection */
833 err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, 0, NULL);
834 }
835
836unlock:
837 hci_dev_unlock_bh(hdev);
838 hci_dev_put(hdev);
839
840 return err;
841}
842
4e51eae9 843static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len)
8962ee74
JH
844{
845 struct hci_dev *hdev;
846 struct mgmt_cp_disconnect *cp;
847 struct hci_cp_disconnect dc;
366a0336 848 struct pending_cmd *cmd;
8962ee74 849 struct hci_conn *conn;
8962ee74
JH
850 int err;
851
852 BT_DBG("");
853
854 cp = (void *) data;
8962ee74 855
bdce7baf
SJ
856 if (len != sizeof(*cp))
857 return cmd_status(sk, index, MGMT_OP_DISCONNECT, EINVAL);
858
4e51eae9 859 hdev = hci_dev_get(index);
8962ee74 860 if (!hdev)
4e51eae9 861 return cmd_status(sk, index, MGMT_OP_DISCONNECT, ENODEV);
8962ee74
JH
862
863 hci_dev_lock_bh(hdev);
864
865 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9 866 err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENETDOWN);
8962ee74
JH
867 goto failed;
868 }
869
4e51eae9
SJ
870 if (mgmt_pending_find(MGMT_OP_DISCONNECT, index)) {
871 err = cmd_status(sk, index, MGMT_OP_DISCONNECT, EBUSY);
8962ee74
JH
872 goto failed;
873 }
874
875 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
876 if (!conn) {
4e51eae9 877 err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENOTCONN);
8962ee74
JH
878 goto failed;
879 }
880
4e51eae9 881 cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, index, data, len);
366a0336
JH
882 if (!cmd) {
883 err = -ENOMEM;
8962ee74 884 goto failed;
366a0336 885 }
8962ee74
JH
886
887 put_unaligned_le16(conn->handle, &dc.handle);
888 dc.reason = 0x13; /* Remote User Terminated Connection */
889
890 err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc);
891 if (err < 0)
a664b5bc 892 mgmt_pending_remove(cmd);
8962ee74
JH
893
894failed:
895 hci_dev_unlock_bh(hdev);
896 hci_dev_put(hdev);
897
898 return err;
899}
900
4e51eae9
SJ
901static int get_connections(struct sock *sk, u16 index, unsigned char *data,
902 u16 len)
2784eb41 903{
2784eb41 904 struct mgmt_cp_get_connections *cp;
2784eb41
JH
905 struct mgmt_rp_get_connections *rp;
906 struct hci_dev *hdev;
907 struct list_head *p;
a38528f1 908 size_t rp_len;
4e51eae9 909 u16 count;
2784eb41
JH
910 int i, err;
911
912 BT_DBG("");
913
914 cp = (void *) data;
2784eb41 915
4e51eae9 916 hdev = hci_dev_get(index);
2784eb41 917 if (!hdev)
4e51eae9 918 return cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS, ENODEV);
2784eb41
JH
919
920 hci_dev_lock_bh(hdev);
921
922 count = 0;
923 list_for_each(p, &hdev->conn_hash.list) {
924 count++;
925 }
926
a38528f1
JH
927 rp_len = sizeof(*rp) + (count * sizeof(bdaddr_t));
928 rp = kmalloc(rp_len, GFP_ATOMIC);
929 if (!rp) {
2784eb41
JH
930 err = -ENOMEM;
931 goto unlock;
932 }
933
2784eb41
JH
934 put_unaligned_le16(count, &rp->conn_count);
935
936 read_lock(&hci_dev_list_lock);
937
938 i = 0;
939 list_for_each(p, &hdev->conn_hash.list) {
940 struct hci_conn *c = list_entry(p, struct hci_conn, list);
941
942 bacpy(&rp->conn[i++], &c->dst);
943 }
944
945 read_unlock(&hci_dev_list_lock);
946
4e51eae9 947 err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len);
2784eb41
JH
948
949unlock:
a38528f1 950 kfree(rp);
2784eb41
JH
951 hci_dev_unlock_bh(hdev);
952 hci_dev_put(hdev);
953 return err;
954}
955
4e51eae9
SJ
956static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data,
957 u16 len)
980e1a53
JH
958{
959 struct hci_dev *hdev;
960 struct mgmt_cp_pin_code_reply *cp;
961 struct hci_cp_pin_code_reply reply;
366a0336 962 struct pending_cmd *cmd;
980e1a53
JH
963 int err;
964
965 BT_DBG("");
966
967 cp = (void *) data;
980e1a53 968
bdce7baf
SJ
969 if (len != sizeof(*cp))
970 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, EINVAL);
971
4e51eae9 972 hdev = hci_dev_get(index);
980e1a53 973 if (!hdev)
4e51eae9 974 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENODEV);
980e1a53
JH
975
976 hci_dev_lock_bh(hdev);
977
978 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9 979 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENETDOWN);
980e1a53
JH
980 goto failed;
981 }
982
4e51eae9 983 cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, index, data, len);
366a0336
JH
984 if (!cmd) {
985 err = -ENOMEM;
980e1a53 986 goto failed;
366a0336 987 }
980e1a53
JH
988
989 bacpy(&reply.bdaddr, &cp->bdaddr);
990 reply.pin_len = cp->pin_len;
991 memcpy(reply.pin_code, cp->pin_code, 16);
992
993 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_REPLY, sizeof(reply), &reply);
994 if (err < 0)
a664b5bc 995 mgmt_pending_remove(cmd);
980e1a53
JH
996
997failed:
998 hci_dev_unlock_bh(hdev);
999 hci_dev_put(hdev);
1000
1001 return err;
1002}
1003
4e51eae9
SJ
1004static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data,
1005 u16 len)
980e1a53
JH
1006{
1007 struct hci_dev *hdev;
1008 struct mgmt_cp_pin_code_neg_reply *cp;
366a0336 1009 struct pending_cmd *cmd;
980e1a53
JH
1010 int err;
1011
1012 BT_DBG("");
1013
1014 cp = (void *) data;
980e1a53 1015
bdce7baf
SJ
1016 if (len != sizeof(*cp))
1017 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
1018 EINVAL);
1019
4e51eae9 1020 hdev = hci_dev_get(index);
980e1a53 1021 if (!hdev)
4e51eae9
SJ
1022 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
1023 ENODEV);
980e1a53
JH
1024
1025 hci_dev_lock_bh(hdev);
1026
1027 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9
SJ
1028 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
1029 ENETDOWN);
980e1a53
JH
1030 goto failed;
1031 }
1032
4e51eae9 1033 cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, index,
980e1a53 1034 data, len);
366a0336
JH
1035 if (!cmd) {
1036 err = -ENOMEM;
980e1a53 1037 goto failed;
366a0336 1038 }
980e1a53
JH
1039
1040 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(bdaddr_t),
1041 &cp->bdaddr);
1042 if (err < 0)
a664b5bc 1043 mgmt_pending_remove(cmd);
980e1a53
JH
1044
1045failed:
1046 hci_dev_unlock_bh(hdev);
1047 hci_dev_put(hdev);
1048
1049 return err;
1050}
1051
4e51eae9
SJ
1052static int set_io_capability(struct sock *sk, u16 index, unsigned char *data,
1053 u16 len)
17fa4b9d
JH
1054{
1055 struct hci_dev *hdev;
1056 struct mgmt_cp_set_io_capability *cp;
17fa4b9d
JH
1057
1058 BT_DBG("");
1059
1060 cp = (void *) data;
17fa4b9d 1061
bdce7baf
SJ
1062 if (len != sizeof(*cp))
1063 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY,
1064 EINVAL);
1065
4e51eae9 1066 hdev = hci_dev_get(index);
17fa4b9d 1067 if (!hdev)
4e51eae9 1068 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, ENODEV);
17fa4b9d
JH
1069
1070 hci_dev_lock_bh(hdev);
1071
1072 hdev->io_capability = cp->io_capability;
1073
1074 BT_DBG("%s IO capability set to 0x%02x", hdev->name,
1075 hdev->io_capability);
1076
1077 hci_dev_unlock_bh(hdev);
1078 hci_dev_put(hdev);
1079
4e51eae9 1080 return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, NULL, 0);
17fa4b9d
JH
1081}
1082
e9a416b5
JH
1083static inline struct pending_cmd *find_pairing(struct hci_conn *conn)
1084{
1085 struct hci_dev *hdev = conn->hdev;
1086 struct list_head *p;
1087
1088 list_for_each(p, &cmd_list) {
1089 struct pending_cmd *cmd;
1090
1091 cmd = list_entry(p, struct pending_cmd, list);
1092
1093 if (cmd->opcode != MGMT_OP_PAIR_DEVICE)
1094 continue;
1095
1096 if (cmd->index != hdev->id)
1097 continue;
1098
1099 if (cmd->user_data != conn)
1100 continue;
1101
1102 return cmd;
1103 }
1104
1105 return NULL;
1106}
1107
1108static void pairing_complete(struct pending_cmd *cmd, u8 status)
1109{
1110 struct mgmt_rp_pair_device rp;
1111 struct hci_conn *conn = cmd->user_data;
1112
e9a416b5
JH
1113 bacpy(&rp.bdaddr, &conn->dst);
1114 rp.status = status;
1115
4e51eae9 1116 cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, &rp, sizeof(rp));
e9a416b5
JH
1117
1118 /* So we don't get further callbacks for this connection */
1119 conn->connect_cfm_cb = NULL;
1120 conn->security_cfm_cb = NULL;
1121 conn->disconn_cfm_cb = NULL;
1122
1123 hci_conn_put(conn);
1124
a664b5bc 1125 mgmt_pending_remove(cmd);
e9a416b5
JH
1126}
1127
1128static void pairing_complete_cb(struct hci_conn *conn, u8 status)
1129{
1130 struct pending_cmd *cmd;
1131
1132 BT_DBG("status %u", status);
1133
1134 cmd = find_pairing(conn);
1135 if (!cmd) {
1136 BT_DBG("Unable to find a pending command");
1137 return;
1138 }
1139
1140 pairing_complete(cmd, status);
1141}
1142
4e51eae9 1143static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len)
e9a416b5
JH
1144{
1145 struct hci_dev *hdev;
1146 struct mgmt_cp_pair_device *cp;
1147 struct pending_cmd *cmd;
1148 u8 sec_level, auth_type;
1149 struct hci_conn *conn;
e9a416b5
JH
1150 int err;
1151
1152 BT_DBG("");
1153
1154 cp = (void *) data;
e9a416b5 1155
bdce7baf
SJ
1156 if (len != sizeof(*cp))
1157 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, EINVAL);
1158
4e51eae9 1159 hdev = hci_dev_get(index);
e9a416b5 1160 if (!hdev)
4e51eae9 1161 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, ENODEV);
e9a416b5
JH
1162
1163 hci_dev_lock_bh(hdev);
1164
1165 if (cp->io_cap == 0x03) {
1166 sec_level = BT_SECURITY_MEDIUM;
1167 auth_type = HCI_AT_DEDICATED_BONDING;
1168 } else {
1169 sec_level = BT_SECURITY_HIGH;
1170 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
1171 }
1172
1173 conn = hci_connect(hdev, ACL_LINK, &cp->bdaddr, sec_level, auth_type);
1174 if (!conn) {
1175 err = -ENOMEM;
1176 goto unlock;
1177 }
1178
1179 if (conn->connect_cfm_cb) {
1180 hci_conn_put(conn);
4e51eae9 1181 err = cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, EBUSY);
e9a416b5
JH
1182 goto unlock;
1183 }
1184
4e51eae9 1185 cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, index, data, len);
e9a416b5
JH
1186 if (!cmd) {
1187 err = -ENOMEM;
1188 hci_conn_put(conn);
1189 goto unlock;
1190 }
1191
1192 conn->connect_cfm_cb = pairing_complete_cb;
1193 conn->security_cfm_cb = pairing_complete_cb;
1194 conn->disconn_cfm_cb = pairing_complete_cb;
1195 conn->io_capability = cp->io_cap;
1196 cmd->user_data = conn;
1197
1198 if (conn->state == BT_CONNECTED &&
1199 hci_conn_security(conn, sec_level, auth_type))
1200 pairing_complete(cmd, 0);
1201
1202 err = 0;
1203
1204unlock:
1205 hci_dev_unlock_bh(hdev);
1206 hci_dev_put(hdev);
1207
1208 return err;
1209}
1210
4e51eae9
SJ
1211static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data,
1212 u16 len, int success)
a5c29683
JH
1213{
1214 struct mgmt_cp_user_confirm_reply *cp = (void *) data;
4e51eae9 1215 u16 mgmt_op, hci_op;
a5c29683
JH
1216 struct pending_cmd *cmd;
1217 struct hci_dev *hdev;
1218 int err;
1219
1220 BT_DBG("");
1221
a5c29683
JH
1222 if (success) {
1223 mgmt_op = MGMT_OP_USER_CONFIRM_REPLY;
1224 hci_op = HCI_OP_USER_CONFIRM_REPLY;
1225 } else {
1226 mgmt_op = MGMT_OP_USER_CONFIRM_NEG_REPLY;
1227 hci_op = HCI_OP_USER_CONFIRM_NEG_REPLY;
1228 }
1229
bdce7baf
SJ
1230 if (len != sizeof(*cp))
1231 return cmd_status(sk, index, mgmt_op, EINVAL);
1232
4e51eae9 1233 hdev = hci_dev_get(index);
a5c29683 1234 if (!hdev)
4e51eae9 1235 return cmd_status(sk, index, mgmt_op, ENODEV);
a5c29683
JH
1236
1237 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9 1238 err = cmd_status(sk, index, mgmt_op, ENETDOWN);
a5c29683
JH
1239 goto failed;
1240 }
1241
4e51eae9 1242 cmd = mgmt_pending_add(sk, mgmt_op, index, data, len);
a5c29683
JH
1243 if (!cmd) {
1244 err = -ENOMEM;
1245 goto failed;
1246 }
1247
1248 err = hci_send_cmd(hdev, hci_op, sizeof(cp->bdaddr), &cp->bdaddr);
a664b5bc
JH
1249 if (err < 0)
1250 mgmt_pending_remove(cmd);
a5c29683
JH
1251
1252failed:
1253 hci_dev_unlock_bh(hdev);
1254 hci_dev_put(hdev);
1255
1256 return err;
1257}
1258
0381101f
JH
1259int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
1260{
1261 unsigned char *buf;
1262 struct mgmt_hdr *hdr;
4e51eae9 1263 u16 opcode, index, len;
0381101f
JH
1264 int err;
1265
1266 BT_DBG("got %zu bytes", msglen);
1267
1268 if (msglen < sizeof(*hdr))
1269 return -EINVAL;
1270
1271 buf = kmalloc(msglen, GFP_ATOMIC);
1272 if (!buf)
1273 return -ENOMEM;
1274
1275 if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
1276 err = -EFAULT;
1277 goto done;
1278 }
1279
1280 hdr = (struct mgmt_hdr *) buf;
1281 opcode = get_unaligned_le16(&hdr->opcode);
4e51eae9 1282 index = get_unaligned_le16(&hdr->index);
0381101f
JH
1283 len = get_unaligned_le16(&hdr->len);
1284
1285 if (len != msglen - sizeof(*hdr)) {
1286 err = -EINVAL;
1287 goto done;
1288 }
1289
1290 switch (opcode) {
02d98129
JH
1291 case MGMT_OP_READ_VERSION:
1292 err = read_version(sk);
1293 break;
faba42eb
JH
1294 case MGMT_OP_READ_INDEX_LIST:
1295 err = read_index_list(sk);
1296 break;
f7b64e69 1297 case MGMT_OP_READ_INFO:
4e51eae9 1298 err = read_controller_info(sk, index);
f7b64e69 1299 break;
eec8d2bc 1300 case MGMT_OP_SET_POWERED:
4e51eae9 1301 err = set_powered(sk, index, buf + sizeof(*hdr), len);
eec8d2bc 1302 break;
73f22f62 1303 case MGMT_OP_SET_DISCOVERABLE:
4e51eae9 1304 err = set_discoverable(sk, index, buf + sizeof(*hdr), len);
73f22f62 1305 break;
9fbcbb45 1306 case MGMT_OP_SET_CONNECTABLE:
4e51eae9 1307 err = set_connectable(sk, index, buf + sizeof(*hdr), len);
9fbcbb45 1308 break;
c542a06c 1309 case MGMT_OP_SET_PAIRABLE:
4e51eae9 1310 err = set_pairable(sk, index, buf + sizeof(*hdr), len);
c542a06c 1311 break;
2aeb9a1a 1312 case MGMT_OP_ADD_UUID:
4e51eae9 1313 err = add_uuid(sk, index, buf + sizeof(*hdr), len);
2aeb9a1a
JH
1314 break;
1315 case MGMT_OP_REMOVE_UUID:
4e51eae9 1316 err = remove_uuid(sk, index, buf + sizeof(*hdr), len);
2aeb9a1a 1317 break;
1aff6f09 1318 case MGMT_OP_SET_DEV_CLASS:
4e51eae9 1319 err = set_dev_class(sk, index, buf + sizeof(*hdr), len);
1aff6f09
JH
1320 break;
1321 case MGMT_OP_SET_SERVICE_CACHE:
4e51eae9 1322 err = set_service_cache(sk, index, buf + sizeof(*hdr), len);
1aff6f09 1323 break;
55ed8ca1 1324 case MGMT_OP_LOAD_KEYS:
4e51eae9 1325 err = load_keys(sk, index, buf + sizeof(*hdr), len);
55ed8ca1
JH
1326 break;
1327 case MGMT_OP_REMOVE_KEY:
4e51eae9 1328 err = remove_key(sk, index, buf + sizeof(*hdr), len);
55ed8ca1 1329 break;
8962ee74 1330 case MGMT_OP_DISCONNECT:
4e51eae9 1331 err = disconnect(sk, index, buf + sizeof(*hdr), len);
8962ee74 1332 break;
2784eb41 1333 case MGMT_OP_GET_CONNECTIONS:
4e51eae9 1334 err = get_connections(sk, index, buf + sizeof(*hdr), len);
2784eb41 1335 break;
980e1a53 1336 case MGMT_OP_PIN_CODE_REPLY:
4e51eae9 1337 err = pin_code_reply(sk, index, buf + sizeof(*hdr), len);
980e1a53
JH
1338 break;
1339 case MGMT_OP_PIN_CODE_NEG_REPLY:
4e51eae9 1340 err = pin_code_neg_reply(sk, index, buf + sizeof(*hdr), len);
980e1a53 1341 break;
17fa4b9d 1342 case MGMT_OP_SET_IO_CAPABILITY:
4e51eae9 1343 err = set_io_capability(sk, index, buf + sizeof(*hdr), len);
17fa4b9d 1344 break;
e9a416b5 1345 case MGMT_OP_PAIR_DEVICE:
4e51eae9 1346 err = pair_device(sk, index, buf + sizeof(*hdr), len);
e9a416b5 1347 break;
a5c29683 1348 case MGMT_OP_USER_CONFIRM_REPLY:
4e51eae9 1349 err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 1);
a5c29683
JH
1350 break;
1351 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
4e51eae9 1352 err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 0);
a5c29683 1353 break;
0381101f
JH
1354 default:
1355 BT_DBG("Unknown op %u", opcode);
4e51eae9 1356 err = cmd_status(sk, index, opcode, 0x01);
0381101f
JH
1357 break;
1358 }
1359
e41d8b4e
JH
1360 if (err < 0)
1361 goto done;
1362
0381101f
JH
1363 err = msglen;
1364
1365done:
1366 kfree(buf);
1367 return err;
1368}
c71e97bf 1369
c71e97bf
JH
1370int mgmt_index_added(u16 index)
1371{
4e51eae9 1372 return mgmt_event(MGMT_EV_INDEX_ADDED, index, NULL, 0, NULL);
c71e97bf
JH
1373}
1374
1375int mgmt_index_removed(u16 index)
1376{
4e51eae9 1377 return mgmt_event(MGMT_EV_INDEX_REMOVED, index, NULL, 0, NULL);
eec8d2bc
JH
1378}
1379
73f22f62 1380struct cmd_lookup {
72a734ec 1381 u8 val;
eec8d2bc
JH
1382 struct sock *sk;
1383};
1384
72a734ec 1385static void mode_rsp(struct pending_cmd *cmd, void *data)
eec8d2bc 1386{
72a734ec 1387 struct mgmt_mode *cp = cmd->cmd;
73f22f62 1388 struct cmd_lookup *match = data;
eec8d2bc 1389
72a734ec 1390 if (cp->val != match->val)
eec8d2bc
JH
1391 return;
1392
053f0211 1393 send_mode_rsp(cmd->sk, cmd->opcode, cmd->index, cp->val);
eec8d2bc
JH
1394
1395 list_del(&cmd->list);
1396
1397 if (match->sk == NULL) {
1398 match->sk = cmd->sk;
1399 sock_hold(match->sk);
1400 }
1401
1402 mgmt_pending_free(cmd);
c71e97bf 1403}
5add6af8
JH
1404
1405int mgmt_powered(u16 index, u8 powered)
1406{
72a734ec 1407 struct mgmt_mode ev;
73f22f62 1408 struct cmd_lookup match = { powered, NULL };
eec8d2bc 1409 int ret;
5add6af8 1410
72a734ec 1411 mgmt_pending_foreach(MGMT_OP_SET_POWERED, index, mode_rsp, &match);
5add6af8 1412
72a734ec 1413 ev.val = powered;
eec8d2bc 1414
4e51eae9 1415 ret = mgmt_event(MGMT_EV_POWERED, index, &ev, sizeof(ev), match.sk);
eec8d2bc
JH
1416
1417 if (match.sk)
1418 sock_put(match.sk);
1419
1420 return ret;
5add6af8 1421}
73f22f62 1422
73f22f62
JH
1423int mgmt_discoverable(u16 index, u8 discoverable)
1424{
72a734ec 1425 struct mgmt_mode ev;
73f22f62
JH
1426 struct cmd_lookup match = { discoverable, NULL };
1427 int ret;
1428
73f22f62 1429 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index,
72a734ec
JH
1430 mode_rsp, &match);
1431
72a734ec 1432 ev.val = discoverable;
73f22f62 1433
4e51eae9
SJ
1434 ret = mgmt_event(MGMT_EV_DISCOVERABLE, index, &ev, sizeof(ev),
1435 match.sk);
73f22f62
JH
1436
1437 if (match.sk)
1438 sock_put(match.sk);
1439
1440 return ret;
1441}
9fbcbb45 1442
9fbcbb45
JH
1443int mgmt_connectable(u16 index, u8 connectable)
1444{
72a734ec 1445 struct mgmt_mode ev;
9fbcbb45
JH
1446 struct cmd_lookup match = { connectable, NULL };
1447 int ret;
1448
72a734ec 1449 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index, mode_rsp, &match);
9fbcbb45 1450
72a734ec 1451 ev.val = connectable;
9fbcbb45 1452
4e51eae9 1453 ret = mgmt_event(MGMT_EV_CONNECTABLE, index, &ev, sizeof(ev), match.sk);
9fbcbb45
JH
1454
1455 if (match.sk)
1456 sock_put(match.sk);
1457
1458 return ret;
1459}
55ed8ca1
JH
1460
1461int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type)
1462{
1463 struct mgmt_ev_new_key ev;
1464
1465 memset(&ev, 0, sizeof(ev));
1466
55ed8ca1
JH
1467 bacpy(&ev.key.bdaddr, &key->bdaddr);
1468 ev.key.type = key->type;
1469 memcpy(ev.key.val, key->val, 16);
1470 ev.key.pin_len = key->pin_len;
1471 ev.old_key_type = old_key_type;
1472
4e51eae9 1473 return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL);
55ed8ca1 1474}
f7520543
JH
1475
1476int mgmt_connected(u16 index, bdaddr_t *bdaddr)
1477{
1478 struct mgmt_ev_connected ev;
1479
f7520543
JH
1480 bacpy(&ev.bdaddr, bdaddr);
1481
4e51eae9 1482 return mgmt_event(MGMT_EV_CONNECTED, index, &ev, sizeof(ev), NULL);
f7520543
JH
1483}
1484
8962ee74
JH
1485static void disconnect_rsp(struct pending_cmd *cmd, void *data)
1486{
1487 struct mgmt_cp_disconnect *cp = cmd->cmd;
1488 struct sock **sk = data;
a38528f1 1489 struct mgmt_rp_disconnect rp;
8962ee74 1490
a38528f1 1491 bacpy(&rp.bdaddr, &cp->bdaddr);
8962ee74 1492
4e51eae9 1493 cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, &rp, sizeof(rp));
8962ee74
JH
1494
1495 *sk = cmd->sk;
1496 sock_hold(*sk);
1497
a664b5bc 1498 mgmt_pending_remove(cmd);
8962ee74
JH
1499}
1500
f7520543
JH
1501int mgmt_disconnected(u16 index, bdaddr_t *bdaddr)
1502{
1503 struct mgmt_ev_disconnected ev;
8962ee74
JH
1504 struct sock *sk = NULL;
1505 int err;
1506
1507 mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk);
f7520543 1508
f7520543
JH
1509 bacpy(&ev.bdaddr, bdaddr);
1510
4e51eae9 1511 err = mgmt_event(MGMT_EV_DISCONNECTED, index, &ev, sizeof(ev), sk);
8962ee74
JH
1512
1513 if (sk)
1514 sock_put(sk);
1515
1516 return err;
1517}
1518
1519int mgmt_disconnect_failed(u16 index)
1520{
1521 struct pending_cmd *cmd;
1522 int err;
1523
1524 cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, index);
1525 if (!cmd)
1526 return -ENOENT;
1527
4e51eae9 1528 err = cmd_status(cmd->sk, index, MGMT_OP_DISCONNECT, EIO);
8962ee74 1529
a664b5bc 1530 mgmt_pending_remove(cmd);
8962ee74
JH
1531
1532 return err;
f7520543 1533}
17d5c04c
JH
1534
1535int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status)
1536{
1537 struct mgmt_ev_connect_failed ev;
1538
17d5c04c
JH
1539 bacpy(&ev.bdaddr, bdaddr);
1540 ev.status = status;
1541
4e51eae9 1542 return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL);
17d5c04c 1543}
980e1a53
JH
1544
1545int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr)
1546{
1547 struct mgmt_ev_pin_code_request ev;
1548
980e1a53
JH
1549 bacpy(&ev.bdaddr, bdaddr);
1550
4e51eae9
SJ
1551 return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev),
1552 NULL);
980e1a53
JH
1553}
1554
1555int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
1556{
1557 struct pending_cmd *cmd;
ac56fb13 1558 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
1559 int err;
1560
1561 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, index);
1562 if (!cmd)
1563 return -ENOENT;
1564
ac56fb13
JH
1565 bacpy(&rp.bdaddr, bdaddr);
1566 rp.status = status;
1567
4e51eae9
SJ
1568 err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_REPLY, &rp,
1569 sizeof(rp));
980e1a53 1570
a664b5bc 1571 mgmt_pending_remove(cmd);
980e1a53
JH
1572
1573 return err;
1574}
1575
1576int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
1577{
1578 struct pending_cmd *cmd;
ac56fb13 1579 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
1580 int err;
1581
1582 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, index);
1583 if (!cmd)
1584 return -ENOENT;
1585
ac56fb13
JH
1586 bacpy(&rp.bdaddr, bdaddr);
1587 rp.status = status;
1588
4e51eae9
SJ
1589 err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, &rp,
1590 sizeof(rp));
980e1a53 1591
a664b5bc 1592 mgmt_pending_remove(cmd);
980e1a53
JH
1593
1594 return err;
1595}
a5c29683
JH
1596
1597int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value)
1598{
1599 struct mgmt_ev_user_confirm_request ev;
1600
1601 BT_DBG("hci%u", index);
1602
a5c29683
JH
1603 bacpy(&ev.bdaddr, bdaddr);
1604 put_unaligned_le32(value, &ev.value);
1605
4e51eae9
SJ
1606 return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev),
1607 NULL);
a5c29683
JH
1608}
1609
1610static int confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status,
1611 u8 opcode)
1612{
1613 struct pending_cmd *cmd;
1614 struct mgmt_rp_user_confirm_reply rp;
1615 int err;
1616
1617 cmd = mgmt_pending_find(opcode, index);
1618 if (!cmd)
1619 return -ENOENT;
1620
a5c29683
JH
1621 bacpy(&rp.bdaddr, bdaddr);
1622 rp.status = status;
4e51eae9 1623 err = cmd_complete(cmd->sk, index, opcode, &rp, sizeof(rp));
a5c29683 1624
a664b5bc 1625 mgmt_pending_remove(cmd);
a5c29683
JH
1626
1627 return err;
1628}
1629
1630int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
1631{
1632 return confirm_reply_complete(index, bdaddr, status,
1633 MGMT_OP_USER_CONFIRM_REPLY);
1634}
1635
1636int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr,
1637 u8 status)
1638{
1639 return confirm_reply_complete(index, bdaddr, status,
1640 MGMT_OP_USER_CONFIRM_NEG_REPLY);
1641}
2a611692
JH
1642
1643int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status)
1644{
1645 struct mgmt_ev_auth_failed ev;
1646
2a611692
JH
1647 bacpy(&ev.bdaddr, bdaddr);
1648 ev.status = status;
1649
4e51eae9 1650 return mgmt_event(MGMT_EV_AUTH_FAILED, index, &ev, sizeof(ev), NULL);
2a611692 1651}