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