Bluetooth: Fix sending LE data over USB
[deliverable/linux.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 718 if (len != sizeof(*cp))
b8534e0f 719 return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, EINVAL);
bdce7baf 720
4e51eae9 721 hdev = hci_dev_get(index);
1aff6f09 722 if (!hdev)
4e51eae9 723 return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, ENODEV);
1aff6f09
JH
724
725 hci_dev_lock_bh(hdev);
726
4e51eae9 727 BT_DBG("hci%u enable %d", index, cp->enable);
1aff6f09
JH
728
729 if (cp->enable) {
730 set_bit(HCI_SERVICE_CACHE, &hdev->flags);
731 err = 0;
732 } else {
733 clear_bit(HCI_SERVICE_CACHE, &hdev->flags);
734 err = update_class(hdev);
735 }
736
737 if (err == 0)
4e51eae9
SJ
738 err = cmd_complete(sk, index, MGMT_OP_SET_SERVICE_CACHE, NULL,
739 0);
1aff6f09
JH
740
741 hci_dev_unlock_bh(hdev);
742 hci_dev_put(hdev);
743
744 return err;
745}
746
4e51eae9 747static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
55ed8ca1
JH
748{
749 struct hci_dev *hdev;
750 struct mgmt_cp_load_keys *cp;
4e51eae9 751 u16 key_count, expected_len;
55ed8ca1
JH
752 int i;
753
754 cp = (void *) data;
bdce7baf
SJ
755
756 if (len < sizeof(*cp))
757 return -EINVAL;
758
55ed8ca1
JH
759 key_count = get_unaligned_le16(&cp->key_count);
760
761 expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info);
762 if (expected_len != len) {
763 BT_ERR("load_keys: expected %u bytes, got %u bytes",
764 len, expected_len);
765 return -EINVAL;
766 }
767
4e51eae9 768 hdev = hci_dev_get(index);
55ed8ca1 769 if (!hdev)
4e51eae9 770 return cmd_status(sk, index, MGMT_OP_LOAD_KEYS, ENODEV);
55ed8ca1 771
4e51eae9 772 BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys,
55ed8ca1
JH
773 key_count);
774
775 hci_dev_lock_bh(hdev);
776
777 hci_link_keys_clear(hdev);
778
779 set_bit(HCI_LINK_KEYS, &hdev->flags);
780
781 if (cp->debug_keys)
782 set_bit(HCI_DEBUG_KEYS, &hdev->flags);
783 else
784 clear_bit(HCI_DEBUG_KEYS, &hdev->flags);
785
786 for (i = 0; i < key_count; i++) {
787 struct mgmt_key_info *key = &cp->keys[i];
788
789 hci_add_link_key(hdev, 0, &key->bdaddr, key->val, key->type,
790 key->pin_len);
791 }
792
793 hci_dev_unlock_bh(hdev);
794 hci_dev_put(hdev);
795
796 return 0;
797}
798
4e51eae9 799static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len)
55ed8ca1
JH
800{
801 struct hci_dev *hdev;
802 struct mgmt_cp_remove_key *cp;
803 struct hci_conn *conn;
55ed8ca1
JH
804 int err;
805
806 cp = (void *) data;
55ed8ca1 807
bdce7baf
SJ
808 if (len != sizeof(*cp))
809 return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, EINVAL);
810
4e51eae9 811 hdev = hci_dev_get(index);
55ed8ca1 812 if (!hdev)
4e51eae9 813 return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, ENODEV);
55ed8ca1
JH
814
815 hci_dev_lock_bh(hdev);
816
817 err = hci_remove_link_key(hdev, &cp->bdaddr);
818 if (err < 0) {
4e51eae9 819 err = cmd_status(sk, index, MGMT_OP_REMOVE_KEY, -err);
55ed8ca1
JH
820 goto unlock;
821 }
822
823 err = 0;
824
825 if (!test_bit(HCI_UP, &hdev->flags) || !cp->disconnect)
826 goto unlock;
827
828 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
829 if (conn) {
830 struct hci_cp_disconnect dc;
831
832 put_unaligned_le16(conn->handle, &dc.handle);
833 dc.reason = 0x13; /* Remote User Terminated Connection */
834 err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, 0, NULL);
835 }
836
837unlock:
838 hci_dev_unlock_bh(hdev);
839 hci_dev_put(hdev);
840
841 return err;
842}
843
4e51eae9 844static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len)
8962ee74
JH
845{
846 struct hci_dev *hdev;
847 struct mgmt_cp_disconnect *cp;
848 struct hci_cp_disconnect dc;
366a0336 849 struct pending_cmd *cmd;
8962ee74 850 struct hci_conn *conn;
8962ee74
JH
851 int err;
852
853 BT_DBG("");
854
855 cp = (void *) data;
8962ee74 856
bdce7baf
SJ
857 if (len != sizeof(*cp))
858 return cmd_status(sk, index, MGMT_OP_DISCONNECT, EINVAL);
859
4e51eae9 860 hdev = hci_dev_get(index);
8962ee74 861 if (!hdev)
4e51eae9 862 return cmd_status(sk, index, MGMT_OP_DISCONNECT, ENODEV);
8962ee74
JH
863
864 hci_dev_lock_bh(hdev);
865
866 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9 867 err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENETDOWN);
8962ee74
JH
868 goto failed;
869 }
870
4e51eae9
SJ
871 if (mgmt_pending_find(MGMT_OP_DISCONNECT, index)) {
872 err = cmd_status(sk, index, MGMT_OP_DISCONNECT, EBUSY);
8962ee74
JH
873 goto failed;
874 }
875
876 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
877 if (!conn) {
4e51eae9 878 err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENOTCONN);
8962ee74
JH
879 goto failed;
880 }
881
4e51eae9 882 cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, index, data, len);
366a0336
JH
883 if (!cmd) {
884 err = -ENOMEM;
8962ee74 885 goto failed;
366a0336 886 }
8962ee74
JH
887
888 put_unaligned_le16(conn->handle, &dc.handle);
889 dc.reason = 0x13; /* Remote User Terminated Connection */
890
891 err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc);
892 if (err < 0)
a664b5bc 893 mgmt_pending_remove(cmd);
8962ee74
JH
894
895failed:
896 hci_dev_unlock_bh(hdev);
897 hci_dev_put(hdev);
898
899 return err;
900}
901
8ce6284e 902static int get_connections(struct sock *sk, u16 index)
2784eb41 903{
2784eb41
JH
904 struct mgmt_rp_get_connections *rp;
905 struct hci_dev *hdev;
906 struct list_head *p;
a38528f1 907 size_t rp_len;
4e51eae9 908 u16 count;
2784eb41
JH
909 int i, err;
910
911 BT_DBG("");
912
4e51eae9 913 hdev = hci_dev_get(index);
2784eb41 914 if (!hdev)
4e51eae9 915 return cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS, ENODEV);
2784eb41
JH
916
917 hci_dev_lock_bh(hdev);
918
919 count = 0;
920 list_for_each(p, &hdev->conn_hash.list) {
921 count++;
922 }
923
a38528f1
JH
924 rp_len = sizeof(*rp) + (count * sizeof(bdaddr_t));
925 rp = kmalloc(rp_len, GFP_ATOMIC);
926 if (!rp) {
2784eb41
JH
927 err = -ENOMEM;
928 goto unlock;
929 }
930
2784eb41
JH
931 put_unaligned_le16(count, &rp->conn_count);
932
933 read_lock(&hci_dev_list_lock);
934
935 i = 0;
936 list_for_each(p, &hdev->conn_hash.list) {
937 struct hci_conn *c = list_entry(p, struct hci_conn, list);
938
939 bacpy(&rp->conn[i++], &c->dst);
940 }
941
942 read_unlock(&hci_dev_list_lock);
943
4e51eae9 944 err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len);
2784eb41
JH
945
946unlock:
a38528f1 947 kfree(rp);
2784eb41
JH
948 hci_dev_unlock_bh(hdev);
949 hci_dev_put(hdev);
950 return err;
951}
952
4e51eae9
SJ
953static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data,
954 u16 len)
980e1a53
JH
955{
956 struct hci_dev *hdev;
957 struct mgmt_cp_pin_code_reply *cp;
958 struct hci_cp_pin_code_reply reply;
366a0336 959 struct pending_cmd *cmd;
980e1a53
JH
960 int err;
961
962 BT_DBG("");
963
964 cp = (void *) data;
980e1a53 965
bdce7baf
SJ
966 if (len != sizeof(*cp))
967 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, EINVAL);
968
4e51eae9 969 hdev = hci_dev_get(index);
980e1a53 970 if (!hdev)
4e51eae9 971 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENODEV);
980e1a53
JH
972
973 hci_dev_lock_bh(hdev);
974
975 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9 976 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENETDOWN);
980e1a53
JH
977 goto failed;
978 }
979
4e51eae9 980 cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, index, data, len);
366a0336
JH
981 if (!cmd) {
982 err = -ENOMEM;
980e1a53 983 goto failed;
366a0336 984 }
980e1a53
JH
985
986 bacpy(&reply.bdaddr, &cp->bdaddr);
987 reply.pin_len = cp->pin_len;
988 memcpy(reply.pin_code, cp->pin_code, 16);
989
990 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_REPLY, sizeof(reply), &reply);
991 if (err < 0)
a664b5bc 992 mgmt_pending_remove(cmd);
980e1a53
JH
993
994failed:
995 hci_dev_unlock_bh(hdev);
996 hci_dev_put(hdev);
997
998 return err;
999}
1000
4e51eae9
SJ
1001static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data,
1002 u16 len)
980e1a53
JH
1003{
1004 struct hci_dev *hdev;
1005 struct mgmt_cp_pin_code_neg_reply *cp;
366a0336 1006 struct pending_cmd *cmd;
980e1a53
JH
1007 int err;
1008
1009 BT_DBG("");
1010
1011 cp = (void *) data;
980e1a53 1012
bdce7baf
SJ
1013 if (len != sizeof(*cp))
1014 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
1015 EINVAL);
1016
4e51eae9 1017 hdev = hci_dev_get(index);
980e1a53 1018 if (!hdev)
4e51eae9
SJ
1019 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
1020 ENODEV);
980e1a53
JH
1021
1022 hci_dev_lock_bh(hdev);
1023
1024 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9
SJ
1025 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
1026 ENETDOWN);
980e1a53
JH
1027 goto failed;
1028 }
1029
4e51eae9 1030 cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, index,
980e1a53 1031 data, len);
366a0336
JH
1032 if (!cmd) {
1033 err = -ENOMEM;
980e1a53 1034 goto failed;
366a0336 1035 }
980e1a53 1036
3cf2a4f6 1037 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(cp->bdaddr),
980e1a53
JH
1038 &cp->bdaddr);
1039 if (err < 0)
a664b5bc 1040 mgmt_pending_remove(cmd);
980e1a53
JH
1041
1042failed:
1043 hci_dev_unlock_bh(hdev);
1044 hci_dev_put(hdev);
1045
1046 return err;
1047}
1048
4e51eae9
SJ
1049static int set_io_capability(struct sock *sk, u16 index, unsigned char *data,
1050 u16 len)
17fa4b9d
JH
1051{
1052 struct hci_dev *hdev;
1053 struct mgmt_cp_set_io_capability *cp;
17fa4b9d
JH
1054
1055 BT_DBG("");
1056
1057 cp = (void *) data;
17fa4b9d 1058
bdce7baf 1059 if (len != sizeof(*cp))
b8534e0f 1060 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, EINVAL);
bdce7baf 1061
4e51eae9 1062 hdev = hci_dev_get(index);
17fa4b9d 1063 if (!hdev)
4e51eae9 1064 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, ENODEV);
17fa4b9d
JH
1065
1066 hci_dev_lock_bh(hdev);
1067
1068 hdev->io_capability = cp->io_capability;
1069
1070 BT_DBG("%s IO capability set to 0x%02x", hdev->name,
b8534e0f 1071 hdev->io_capability);
17fa4b9d
JH
1072
1073 hci_dev_unlock_bh(hdev);
1074 hci_dev_put(hdev);
1075
4e51eae9 1076 return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, NULL, 0);
17fa4b9d
JH
1077}
1078
e9a416b5
JH
1079static inline struct pending_cmd *find_pairing(struct hci_conn *conn)
1080{
1081 struct hci_dev *hdev = conn->hdev;
1082 struct list_head *p;
1083
1084 list_for_each(p, &cmd_list) {
1085 struct pending_cmd *cmd;
1086
1087 cmd = list_entry(p, struct pending_cmd, list);
1088
1089 if (cmd->opcode != MGMT_OP_PAIR_DEVICE)
1090 continue;
1091
1092 if (cmd->index != hdev->id)
1093 continue;
1094
1095 if (cmd->user_data != conn)
1096 continue;
1097
1098 return cmd;
1099 }
1100
1101 return NULL;
1102}
1103
1104static void pairing_complete(struct pending_cmd *cmd, u8 status)
1105{
1106 struct mgmt_rp_pair_device rp;
1107 struct hci_conn *conn = cmd->user_data;
1108
e9a416b5
JH
1109 bacpy(&rp.bdaddr, &conn->dst);
1110 rp.status = status;
1111
4e51eae9 1112 cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, &rp, sizeof(rp));
e9a416b5
JH
1113
1114 /* So we don't get further callbacks for this connection */
1115 conn->connect_cfm_cb = NULL;
1116 conn->security_cfm_cb = NULL;
1117 conn->disconn_cfm_cb = NULL;
1118
1119 hci_conn_put(conn);
1120
a664b5bc 1121 mgmt_pending_remove(cmd);
e9a416b5
JH
1122}
1123
1124static void pairing_complete_cb(struct hci_conn *conn, u8 status)
1125{
1126 struct pending_cmd *cmd;
1127
1128 BT_DBG("status %u", status);
1129
1130 cmd = find_pairing(conn);
1131 if (!cmd) {
1132 BT_DBG("Unable to find a pending command");
1133 return;
1134 }
1135
1136 pairing_complete(cmd, status);
1137}
1138
4e51eae9 1139static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len)
e9a416b5
JH
1140{
1141 struct hci_dev *hdev;
1142 struct mgmt_cp_pair_device *cp;
1143 struct pending_cmd *cmd;
1144 u8 sec_level, auth_type;
1145 struct hci_conn *conn;
e9a416b5
JH
1146 int err;
1147
1148 BT_DBG("");
1149
1150 cp = (void *) data;
e9a416b5 1151
bdce7baf
SJ
1152 if (len != sizeof(*cp))
1153 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, EINVAL);
1154
4e51eae9 1155 hdev = hci_dev_get(index);
e9a416b5 1156 if (!hdev)
4e51eae9 1157 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, ENODEV);
e9a416b5
JH
1158
1159 hci_dev_lock_bh(hdev);
1160
1161 if (cp->io_cap == 0x03) {
1162 sec_level = BT_SECURITY_MEDIUM;
1163 auth_type = HCI_AT_DEDICATED_BONDING;
1164 } else {
1165 sec_level = BT_SECURITY_HIGH;
1166 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
1167 }
1168
1169 conn = hci_connect(hdev, ACL_LINK, &cp->bdaddr, sec_level, auth_type);
30e76272
VT
1170 if (IS_ERR(conn)) {
1171 err = PTR_ERR(conn);
e9a416b5
JH
1172 goto unlock;
1173 }
1174
1175 if (conn->connect_cfm_cb) {
1176 hci_conn_put(conn);
4e51eae9 1177 err = cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, EBUSY);
e9a416b5
JH
1178 goto unlock;
1179 }
1180
4e51eae9 1181 cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, index, data, len);
e9a416b5
JH
1182 if (!cmd) {
1183 err = -ENOMEM;
1184 hci_conn_put(conn);
1185 goto unlock;
1186 }
1187
1188 conn->connect_cfm_cb = pairing_complete_cb;
1189 conn->security_cfm_cb = pairing_complete_cb;
1190 conn->disconn_cfm_cb = pairing_complete_cb;
1191 conn->io_capability = cp->io_cap;
1192 cmd->user_data = conn;
1193
1194 if (conn->state == BT_CONNECTED &&
1195 hci_conn_security(conn, sec_level, auth_type))
1196 pairing_complete(cmd, 0);
1197
1198 err = 0;
1199
1200unlock:
1201 hci_dev_unlock_bh(hdev);
1202 hci_dev_put(hdev);
1203
1204 return err;
1205}
1206
4e51eae9
SJ
1207static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data,
1208 u16 len, int success)
a5c29683
JH
1209{
1210 struct mgmt_cp_user_confirm_reply *cp = (void *) data;
4e51eae9 1211 u16 mgmt_op, hci_op;
a5c29683
JH
1212 struct pending_cmd *cmd;
1213 struct hci_dev *hdev;
1214 int err;
1215
1216 BT_DBG("");
1217
a5c29683
JH
1218 if (success) {
1219 mgmt_op = MGMT_OP_USER_CONFIRM_REPLY;
1220 hci_op = HCI_OP_USER_CONFIRM_REPLY;
1221 } else {
1222 mgmt_op = MGMT_OP_USER_CONFIRM_NEG_REPLY;
1223 hci_op = HCI_OP_USER_CONFIRM_NEG_REPLY;
1224 }
1225
bdce7baf
SJ
1226 if (len != sizeof(*cp))
1227 return cmd_status(sk, index, mgmt_op, EINVAL);
1228
4e51eae9 1229 hdev = hci_dev_get(index);
a5c29683 1230 if (!hdev)
4e51eae9 1231 return cmd_status(sk, index, mgmt_op, ENODEV);
a5c29683
JH
1232
1233 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9 1234 err = cmd_status(sk, index, mgmt_op, ENETDOWN);
a5c29683
JH
1235 goto failed;
1236 }
1237
4e51eae9 1238 cmd = mgmt_pending_add(sk, mgmt_op, index, data, len);
a5c29683
JH
1239 if (!cmd) {
1240 err = -ENOMEM;
1241 goto failed;
1242 }
1243
1244 err = hci_send_cmd(hdev, hci_op, sizeof(cp->bdaddr), &cp->bdaddr);
a664b5bc
JH
1245 if (err < 0)
1246 mgmt_pending_remove(cmd);
a5c29683
JH
1247
1248failed:
1249 hci_dev_unlock_bh(hdev);
1250 hci_dev_put(hdev);
1251
1252 return err;
1253}
1254
0381101f
JH
1255int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
1256{
1257 unsigned char *buf;
1258 struct mgmt_hdr *hdr;
4e51eae9 1259 u16 opcode, index, len;
0381101f
JH
1260 int err;
1261
1262 BT_DBG("got %zu bytes", msglen);
1263
1264 if (msglen < sizeof(*hdr))
1265 return -EINVAL;
1266
1267 buf = kmalloc(msglen, GFP_ATOMIC);
1268 if (!buf)
1269 return -ENOMEM;
1270
1271 if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
1272 err = -EFAULT;
1273 goto done;
1274 }
1275
1276 hdr = (struct mgmt_hdr *) buf;
1277 opcode = get_unaligned_le16(&hdr->opcode);
4e51eae9 1278 index = get_unaligned_le16(&hdr->index);
0381101f
JH
1279 len = get_unaligned_le16(&hdr->len);
1280
1281 if (len != msglen - sizeof(*hdr)) {
1282 err = -EINVAL;
1283 goto done;
1284 }
1285
1286 switch (opcode) {
02d98129
JH
1287 case MGMT_OP_READ_VERSION:
1288 err = read_version(sk);
1289 break;
faba42eb
JH
1290 case MGMT_OP_READ_INDEX_LIST:
1291 err = read_index_list(sk);
1292 break;
f7b64e69 1293 case MGMT_OP_READ_INFO:
4e51eae9 1294 err = read_controller_info(sk, index);
f7b64e69 1295 break;
eec8d2bc 1296 case MGMT_OP_SET_POWERED:
4e51eae9 1297 err = set_powered(sk, index, buf + sizeof(*hdr), len);
eec8d2bc 1298 break;
73f22f62 1299 case MGMT_OP_SET_DISCOVERABLE:
4e51eae9 1300 err = set_discoverable(sk, index, buf + sizeof(*hdr), len);
73f22f62 1301 break;
9fbcbb45 1302 case MGMT_OP_SET_CONNECTABLE:
4e51eae9 1303 err = set_connectable(sk, index, buf + sizeof(*hdr), len);
9fbcbb45 1304 break;
c542a06c 1305 case MGMT_OP_SET_PAIRABLE:
4e51eae9 1306 err = set_pairable(sk, index, buf + sizeof(*hdr), len);
c542a06c 1307 break;
2aeb9a1a 1308 case MGMT_OP_ADD_UUID:
4e51eae9 1309 err = add_uuid(sk, index, buf + sizeof(*hdr), len);
2aeb9a1a
JH
1310 break;
1311 case MGMT_OP_REMOVE_UUID:
4e51eae9 1312 err = remove_uuid(sk, index, buf + sizeof(*hdr), len);
2aeb9a1a 1313 break;
1aff6f09 1314 case MGMT_OP_SET_DEV_CLASS:
4e51eae9 1315 err = set_dev_class(sk, index, buf + sizeof(*hdr), len);
1aff6f09
JH
1316 break;
1317 case MGMT_OP_SET_SERVICE_CACHE:
4e51eae9 1318 err = set_service_cache(sk, index, buf + sizeof(*hdr), len);
1aff6f09 1319 break;
55ed8ca1 1320 case MGMT_OP_LOAD_KEYS:
4e51eae9 1321 err = load_keys(sk, index, buf + sizeof(*hdr), len);
55ed8ca1
JH
1322 break;
1323 case MGMT_OP_REMOVE_KEY:
4e51eae9 1324 err = remove_key(sk, index, buf + sizeof(*hdr), len);
55ed8ca1 1325 break;
8962ee74 1326 case MGMT_OP_DISCONNECT:
4e51eae9 1327 err = disconnect(sk, index, buf + sizeof(*hdr), len);
8962ee74 1328 break;
2784eb41 1329 case MGMT_OP_GET_CONNECTIONS:
8ce6284e 1330 err = get_connections(sk, index);
2784eb41 1331 break;
980e1a53 1332 case MGMT_OP_PIN_CODE_REPLY:
4e51eae9 1333 err = pin_code_reply(sk, index, buf + sizeof(*hdr), len);
980e1a53
JH
1334 break;
1335 case MGMT_OP_PIN_CODE_NEG_REPLY:
4e51eae9 1336 err = pin_code_neg_reply(sk, index, buf + sizeof(*hdr), len);
980e1a53 1337 break;
17fa4b9d 1338 case MGMT_OP_SET_IO_CAPABILITY:
4e51eae9 1339 err = set_io_capability(sk, index, buf + sizeof(*hdr), len);
17fa4b9d 1340 break;
e9a416b5 1341 case MGMT_OP_PAIR_DEVICE:
4e51eae9 1342 err = pair_device(sk, index, buf + sizeof(*hdr), len);
e9a416b5 1343 break;
a5c29683 1344 case MGMT_OP_USER_CONFIRM_REPLY:
4e51eae9 1345 err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 1);
a5c29683
JH
1346 break;
1347 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
4e51eae9 1348 err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 0);
a5c29683 1349 break;
0381101f
JH
1350 default:
1351 BT_DBG("Unknown op %u", opcode);
4e51eae9 1352 err = cmd_status(sk, index, opcode, 0x01);
0381101f
JH
1353 break;
1354 }
1355
e41d8b4e
JH
1356 if (err < 0)
1357 goto done;
1358
0381101f
JH
1359 err = msglen;
1360
1361done:
1362 kfree(buf);
1363 return err;
1364}
c71e97bf 1365
c71e97bf
JH
1366int mgmt_index_added(u16 index)
1367{
4e51eae9 1368 return mgmt_event(MGMT_EV_INDEX_ADDED, index, NULL, 0, NULL);
c71e97bf
JH
1369}
1370
1371int mgmt_index_removed(u16 index)
1372{
4e51eae9 1373 return mgmt_event(MGMT_EV_INDEX_REMOVED, index, NULL, 0, NULL);
eec8d2bc
JH
1374}
1375
73f22f62 1376struct cmd_lookup {
72a734ec 1377 u8 val;
eec8d2bc
JH
1378 struct sock *sk;
1379};
1380
72a734ec 1381static void mode_rsp(struct pending_cmd *cmd, void *data)
eec8d2bc 1382{
72a734ec 1383 struct mgmt_mode *cp = cmd->cmd;
73f22f62 1384 struct cmd_lookup *match = data;
eec8d2bc 1385
72a734ec 1386 if (cp->val != match->val)
eec8d2bc
JH
1387 return;
1388
053f0211 1389 send_mode_rsp(cmd->sk, cmd->opcode, cmd->index, cp->val);
eec8d2bc
JH
1390
1391 list_del(&cmd->list);
1392
1393 if (match->sk == NULL) {
1394 match->sk = cmd->sk;
1395 sock_hold(match->sk);
1396 }
1397
1398 mgmt_pending_free(cmd);
c71e97bf 1399}
5add6af8
JH
1400
1401int mgmt_powered(u16 index, u8 powered)
1402{
72a734ec 1403 struct mgmt_mode ev;
73f22f62 1404 struct cmd_lookup match = { powered, NULL };
eec8d2bc 1405 int ret;
5add6af8 1406
72a734ec 1407 mgmt_pending_foreach(MGMT_OP_SET_POWERED, index, mode_rsp, &match);
5add6af8 1408
72a734ec 1409 ev.val = powered;
eec8d2bc 1410
4e51eae9 1411 ret = mgmt_event(MGMT_EV_POWERED, index, &ev, sizeof(ev), match.sk);
eec8d2bc
JH
1412
1413 if (match.sk)
1414 sock_put(match.sk);
1415
1416 return ret;
5add6af8 1417}
73f22f62 1418
73f22f62
JH
1419int mgmt_discoverable(u16 index, u8 discoverable)
1420{
72a734ec 1421 struct mgmt_mode ev;
73f22f62
JH
1422 struct cmd_lookup match = { discoverable, NULL };
1423 int ret;
1424
b8534e0f 1425 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index, mode_rsp, &match);
72a734ec 1426
72a734ec 1427 ev.val = discoverable;
73f22f62 1428
4e51eae9
SJ
1429 ret = mgmt_event(MGMT_EV_DISCOVERABLE, index, &ev, sizeof(ev),
1430 match.sk);
73f22f62
JH
1431
1432 if (match.sk)
1433 sock_put(match.sk);
1434
1435 return ret;
1436}
9fbcbb45 1437
9fbcbb45
JH
1438int mgmt_connectable(u16 index, u8 connectable)
1439{
72a734ec 1440 struct mgmt_mode ev;
9fbcbb45
JH
1441 struct cmd_lookup match = { connectable, NULL };
1442 int ret;
1443
72a734ec 1444 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index, mode_rsp, &match);
9fbcbb45 1445
72a734ec 1446 ev.val = connectable;
9fbcbb45 1447
4e51eae9 1448 ret = mgmt_event(MGMT_EV_CONNECTABLE, index, &ev, sizeof(ev), match.sk);
9fbcbb45
JH
1449
1450 if (match.sk)
1451 sock_put(match.sk);
1452
1453 return ret;
1454}
55ed8ca1
JH
1455
1456int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type)
1457{
1458 struct mgmt_ev_new_key ev;
1459
1460 memset(&ev, 0, sizeof(ev));
1461
55ed8ca1
JH
1462 bacpy(&ev.key.bdaddr, &key->bdaddr);
1463 ev.key.type = key->type;
1464 memcpy(ev.key.val, key->val, 16);
1465 ev.key.pin_len = key->pin_len;
1466 ev.old_key_type = old_key_type;
1467
4e51eae9 1468 return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL);
55ed8ca1 1469}
f7520543
JH
1470
1471int mgmt_connected(u16 index, bdaddr_t *bdaddr)
1472{
1473 struct mgmt_ev_connected ev;
1474
f7520543
JH
1475 bacpy(&ev.bdaddr, bdaddr);
1476
4e51eae9 1477 return mgmt_event(MGMT_EV_CONNECTED, index, &ev, sizeof(ev), NULL);
f7520543
JH
1478}
1479
8962ee74
JH
1480static void disconnect_rsp(struct pending_cmd *cmd, void *data)
1481{
1482 struct mgmt_cp_disconnect *cp = cmd->cmd;
1483 struct sock **sk = data;
a38528f1 1484 struct mgmt_rp_disconnect rp;
8962ee74 1485
a38528f1 1486 bacpy(&rp.bdaddr, &cp->bdaddr);
8962ee74 1487
4e51eae9 1488 cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, &rp, sizeof(rp));
8962ee74
JH
1489
1490 *sk = cmd->sk;
1491 sock_hold(*sk);
1492
a664b5bc 1493 mgmt_pending_remove(cmd);
8962ee74
JH
1494}
1495
f7520543
JH
1496int mgmt_disconnected(u16 index, bdaddr_t *bdaddr)
1497{
1498 struct mgmt_ev_disconnected ev;
8962ee74
JH
1499 struct sock *sk = NULL;
1500 int err;
1501
1502 mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk);
f7520543 1503
f7520543
JH
1504 bacpy(&ev.bdaddr, bdaddr);
1505
4e51eae9 1506 err = mgmt_event(MGMT_EV_DISCONNECTED, index, &ev, sizeof(ev), sk);
8962ee74
JH
1507
1508 if (sk)
1509 sock_put(sk);
1510
1511 return err;
1512}
1513
1514int mgmt_disconnect_failed(u16 index)
1515{
1516 struct pending_cmd *cmd;
1517 int err;
1518
1519 cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, index);
1520 if (!cmd)
1521 return -ENOENT;
1522
4e51eae9 1523 err = cmd_status(cmd->sk, index, MGMT_OP_DISCONNECT, EIO);
8962ee74 1524
a664b5bc 1525 mgmt_pending_remove(cmd);
8962ee74
JH
1526
1527 return err;
f7520543 1528}
17d5c04c
JH
1529
1530int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status)
1531{
1532 struct mgmt_ev_connect_failed ev;
1533
17d5c04c
JH
1534 bacpy(&ev.bdaddr, bdaddr);
1535 ev.status = status;
1536
4e51eae9 1537 return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL);
17d5c04c 1538}
980e1a53
JH
1539
1540int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr)
1541{
1542 struct mgmt_ev_pin_code_request ev;
1543
980e1a53
JH
1544 bacpy(&ev.bdaddr, bdaddr);
1545
4e51eae9
SJ
1546 return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev),
1547 NULL);
980e1a53
JH
1548}
1549
1550int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
1551{
1552 struct pending_cmd *cmd;
ac56fb13 1553 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
1554 int err;
1555
1556 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, index);
1557 if (!cmd)
1558 return -ENOENT;
1559
ac56fb13
JH
1560 bacpy(&rp.bdaddr, bdaddr);
1561 rp.status = status;
1562
4e51eae9
SJ
1563 err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_REPLY, &rp,
1564 sizeof(rp));
980e1a53 1565
a664b5bc 1566 mgmt_pending_remove(cmd);
980e1a53
JH
1567
1568 return err;
1569}
1570
1571int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
1572{
1573 struct pending_cmd *cmd;
ac56fb13 1574 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
1575 int err;
1576
1577 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, index);
1578 if (!cmd)
1579 return -ENOENT;
1580
ac56fb13
JH
1581 bacpy(&rp.bdaddr, bdaddr);
1582 rp.status = status;
1583
4e51eae9
SJ
1584 err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, &rp,
1585 sizeof(rp));
980e1a53 1586
a664b5bc 1587 mgmt_pending_remove(cmd);
980e1a53
JH
1588
1589 return err;
1590}
a5c29683
JH
1591
1592int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value)
1593{
1594 struct mgmt_ev_user_confirm_request ev;
1595
1596 BT_DBG("hci%u", index);
1597
a5c29683
JH
1598 bacpy(&ev.bdaddr, bdaddr);
1599 put_unaligned_le32(value, &ev.value);
1600
4e51eae9
SJ
1601 return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev),
1602 NULL);
a5c29683
JH
1603}
1604
1605static int confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status,
1606 u8 opcode)
1607{
1608 struct pending_cmd *cmd;
1609 struct mgmt_rp_user_confirm_reply rp;
1610 int err;
1611
1612 cmd = mgmt_pending_find(opcode, index);
1613 if (!cmd)
1614 return -ENOENT;
1615
a5c29683
JH
1616 bacpy(&rp.bdaddr, bdaddr);
1617 rp.status = status;
4e51eae9 1618 err = cmd_complete(cmd->sk, index, opcode, &rp, sizeof(rp));
a5c29683 1619
a664b5bc 1620 mgmt_pending_remove(cmd);
a5c29683
JH
1621
1622 return err;
1623}
1624
1625int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
1626{
1627 return confirm_reply_complete(index, bdaddr, status,
1628 MGMT_OP_USER_CONFIRM_REPLY);
1629}
1630
b8534e0f 1631int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
a5c29683
JH
1632{
1633 return confirm_reply_complete(index, bdaddr, status,
1634 MGMT_OP_USER_CONFIRM_NEG_REPLY);
1635}
2a611692
JH
1636
1637int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status)
1638{
1639 struct mgmt_ev_auth_failed ev;
1640
2a611692
JH
1641 bacpy(&ev.bdaddr, bdaddr);
1642 ev.status = status;
1643
4e51eae9 1644 return mgmt_event(MGMT_EV_AUTH_FAILED, index, &ev, sizeof(ev), NULL);
2a611692 1645}
This page took 0.128639 seconds and 5 git commands to generate.