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