Bluetooth: mgmt: Add local name information to read_info reply
[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
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);
220 kfree(cmd->cmd);
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
236 cmd->cmd = kmalloc(len, GFP_ATOMIC);
237 if (!cmd->cmd) {
238 kfree(cmd);
366a0336 239 return NULL;
eec8d2bc
JH
240 }
241
242 memcpy(cmd->cmd, data, len);
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
0381101f
JH
1259int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
1260{
1261 unsigned char *buf;
1262 struct mgmt_hdr *hdr;
4e51eae9 1263 u16 opcode, index, len;
0381101f
JH
1264 int err;
1265
1266 BT_DBG("got %zu bytes", msglen);
1267
1268 if (msglen < sizeof(*hdr))
1269 return -EINVAL;
1270
1271 buf = kmalloc(msglen, GFP_ATOMIC);
1272 if (!buf)
1273 return -ENOMEM;
1274
1275 if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
1276 err = -EFAULT;
1277 goto done;
1278 }
1279
1280 hdr = (struct mgmt_hdr *) buf;
1281 opcode = get_unaligned_le16(&hdr->opcode);
4e51eae9 1282 index = get_unaligned_le16(&hdr->index);
0381101f
JH
1283 len = get_unaligned_le16(&hdr->len);
1284
1285 if (len != msglen - sizeof(*hdr)) {
1286 err = -EINVAL;
1287 goto done;
1288 }
1289
1290 switch (opcode) {
02d98129
JH
1291 case MGMT_OP_READ_VERSION:
1292 err = read_version(sk);
1293 break;
faba42eb
JH
1294 case MGMT_OP_READ_INDEX_LIST:
1295 err = read_index_list(sk);
1296 break;
f7b64e69 1297 case MGMT_OP_READ_INFO:
4e51eae9 1298 err = read_controller_info(sk, index);
f7b64e69 1299 break;
eec8d2bc 1300 case MGMT_OP_SET_POWERED:
4e51eae9 1301 err = set_powered(sk, index, buf + sizeof(*hdr), len);
eec8d2bc 1302 break;
73f22f62 1303 case MGMT_OP_SET_DISCOVERABLE:
4e51eae9 1304 err = set_discoverable(sk, index, buf + sizeof(*hdr), len);
73f22f62 1305 break;
9fbcbb45 1306 case MGMT_OP_SET_CONNECTABLE:
4e51eae9 1307 err = set_connectable(sk, index, buf + sizeof(*hdr), len);
9fbcbb45 1308 break;
c542a06c 1309 case MGMT_OP_SET_PAIRABLE:
4e51eae9 1310 err = set_pairable(sk, index, buf + sizeof(*hdr), len);
c542a06c 1311 break;
2aeb9a1a 1312 case MGMT_OP_ADD_UUID:
4e51eae9 1313 err = add_uuid(sk, index, buf + sizeof(*hdr), len);
2aeb9a1a
JH
1314 break;
1315 case MGMT_OP_REMOVE_UUID:
4e51eae9 1316 err = remove_uuid(sk, index, buf + sizeof(*hdr), len);
2aeb9a1a 1317 break;
1aff6f09 1318 case MGMT_OP_SET_DEV_CLASS:
4e51eae9 1319 err = set_dev_class(sk, index, buf + sizeof(*hdr), len);
1aff6f09
JH
1320 break;
1321 case MGMT_OP_SET_SERVICE_CACHE:
4e51eae9 1322 err = set_service_cache(sk, index, buf + sizeof(*hdr), len);
1aff6f09 1323 break;
55ed8ca1 1324 case MGMT_OP_LOAD_KEYS:
4e51eae9 1325 err = load_keys(sk, index, buf + sizeof(*hdr), len);
55ed8ca1
JH
1326 break;
1327 case MGMT_OP_REMOVE_KEY:
4e51eae9 1328 err = remove_key(sk, index, buf + sizeof(*hdr), len);
55ed8ca1 1329 break;
8962ee74 1330 case MGMT_OP_DISCONNECT:
4e51eae9 1331 err = disconnect(sk, index, buf + sizeof(*hdr), len);
8962ee74 1332 break;
2784eb41 1333 case MGMT_OP_GET_CONNECTIONS:
8ce6284e 1334 err = get_connections(sk, index);
2784eb41 1335 break;
980e1a53 1336 case MGMT_OP_PIN_CODE_REPLY:
4e51eae9 1337 err = pin_code_reply(sk, index, buf + sizeof(*hdr), len);
980e1a53
JH
1338 break;
1339 case MGMT_OP_PIN_CODE_NEG_REPLY:
4e51eae9 1340 err = pin_code_neg_reply(sk, index, buf + sizeof(*hdr), len);
980e1a53 1341 break;
17fa4b9d 1342 case MGMT_OP_SET_IO_CAPABILITY:
4e51eae9 1343 err = set_io_capability(sk, index, buf + sizeof(*hdr), len);
17fa4b9d 1344 break;
e9a416b5 1345 case MGMT_OP_PAIR_DEVICE:
4e51eae9 1346 err = pair_device(sk, index, buf + sizeof(*hdr), len);
e9a416b5 1347 break;
a5c29683 1348 case MGMT_OP_USER_CONFIRM_REPLY:
4e51eae9 1349 err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 1);
a5c29683
JH
1350 break;
1351 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
4e51eae9 1352 err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 0);
a5c29683 1353 break;
0381101f
JH
1354 default:
1355 BT_DBG("Unknown op %u", opcode);
4e51eae9 1356 err = cmd_status(sk, index, opcode, 0x01);
0381101f
JH
1357 break;
1358 }
1359
e41d8b4e
JH
1360 if (err < 0)
1361 goto done;
1362
0381101f
JH
1363 err = msglen;
1364
1365done:
1366 kfree(buf);
1367 return err;
1368}
c71e97bf 1369
c71e97bf
JH
1370int mgmt_index_added(u16 index)
1371{
4e51eae9 1372 return mgmt_event(MGMT_EV_INDEX_ADDED, index, NULL, 0, NULL);
c71e97bf
JH
1373}
1374
1375int mgmt_index_removed(u16 index)
1376{
4e51eae9 1377 return mgmt_event(MGMT_EV_INDEX_REMOVED, index, NULL, 0, NULL);
eec8d2bc
JH
1378}
1379
73f22f62 1380struct cmd_lookup {
72a734ec 1381 u8 val;
eec8d2bc
JH
1382 struct sock *sk;
1383};
1384
72a734ec 1385static void mode_rsp(struct pending_cmd *cmd, void *data)
eec8d2bc 1386{
72a734ec 1387 struct mgmt_mode *cp = cmd->cmd;
73f22f62 1388 struct cmd_lookup *match = data;
eec8d2bc 1389
72a734ec 1390 if (cp->val != match->val)
eec8d2bc
JH
1391 return;
1392
053f0211 1393 send_mode_rsp(cmd->sk, cmd->opcode, cmd->index, cp->val);
eec8d2bc
JH
1394
1395 list_del(&cmd->list);
1396
1397 if (match->sk == NULL) {
1398 match->sk = cmd->sk;
1399 sock_hold(match->sk);
1400 }
1401
1402 mgmt_pending_free(cmd);
c71e97bf 1403}
5add6af8
JH
1404
1405int mgmt_powered(u16 index, u8 powered)
1406{
72a734ec 1407 struct mgmt_mode ev;
73f22f62 1408 struct cmd_lookup match = { powered, NULL };
eec8d2bc 1409 int ret;
5add6af8 1410
72a734ec 1411 mgmt_pending_foreach(MGMT_OP_SET_POWERED, index, mode_rsp, &match);
5add6af8 1412
72a734ec 1413 ev.val = powered;
eec8d2bc 1414
4e51eae9 1415 ret = mgmt_event(MGMT_EV_POWERED, index, &ev, sizeof(ev), match.sk);
eec8d2bc
JH
1416
1417 if (match.sk)
1418 sock_put(match.sk);
1419
1420 return ret;
5add6af8 1421}
73f22f62 1422
73f22f62
JH
1423int mgmt_discoverable(u16 index, u8 discoverable)
1424{
72a734ec 1425 struct mgmt_mode ev;
73f22f62
JH
1426 struct cmd_lookup match = { discoverable, NULL };
1427 int ret;
1428
b8534e0f 1429 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index, mode_rsp, &match);
72a734ec 1430
72a734ec 1431 ev.val = discoverable;
73f22f62 1432
4e51eae9
SJ
1433 ret = mgmt_event(MGMT_EV_DISCOVERABLE, index, &ev, sizeof(ev),
1434 match.sk);
73f22f62
JH
1435
1436 if (match.sk)
1437 sock_put(match.sk);
1438
1439 return ret;
1440}
9fbcbb45 1441
9fbcbb45
JH
1442int mgmt_connectable(u16 index, u8 connectable)
1443{
72a734ec 1444 struct mgmt_mode ev;
9fbcbb45
JH
1445 struct cmd_lookup match = { connectable, NULL };
1446 int ret;
1447
72a734ec 1448 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index, mode_rsp, &match);
9fbcbb45 1449
72a734ec 1450 ev.val = connectable;
9fbcbb45 1451
4e51eae9 1452 ret = mgmt_event(MGMT_EV_CONNECTABLE, index, &ev, sizeof(ev), match.sk);
9fbcbb45
JH
1453
1454 if (match.sk)
1455 sock_put(match.sk);
1456
1457 return ret;
1458}
55ed8ca1
JH
1459
1460int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type)
1461{
1462 struct mgmt_ev_new_key ev;
1463
1464 memset(&ev, 0, sizeof(ev));
1465
55ed8ca1
JH
1466 bacpy(&ev.key.bdaddr, &key->bdaddr);
1467 ev.key.type = key->type;
1468 memcpy(ev.key.val, key->val, 16);
1469 ev.key.pin_len = key->pin_len;
1470 ev.old_key_type = old_key_type;
1471
4e51eae9 1472 return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL);
55ed8ca1 1473}
f7520543
JH
1474
1475int mgmt_connected(u16 index, bdaddr_t *bdaddr)
1476{
1477 struct mgmt_ev_connected ev;
1478
f7520543
JH
1479 bacpy(&ev.bdaddr, bdaddr);
1480
4e51eae9 1481 return mgmt_event(MGMT_EV_CONNECTED, index, &ev, sizeof(ev), NULL);
f7520543
JH
1482}
1483
8962ee74
JH
1484static void disconnect_rsp(struct pending_cmd *cmd, void *data)
1485{
1486 struct mgmt_cp_disconnect *cp = cmd->cmd;
1487 struct sock **sk = data;
a38528f1 1488 struct mgmt_rp_disconnect rp;
8962ee74 1489
a38528f1 1490 bacpy(&rp.bdaddr, &cp->bdaddr);
8962ee74 1491
4e51eae9 1492 cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, &rp, sizeof(rp));
8962ee74
JH
1493
1494 *sk = cmd->sk;
1495 sock_hold(*sk);
1496
a664b5bc 1497 mgmt_pending_remove(cmd);
8962ee74
JH
1498}
1499
f7520543
JH
1500int mgmt_disconnected(u16 index, bdaddr_t *bdaddr)
1501{
1502 struct mgmt_ev_disconnected ev;
8962ee74
JH
1503 struct sock *sk = NULL;
1504 int err;
1505
1506 mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk);
f7520543 1507
f7520543
JH
1508 bacpy(&ev.bdaddr, bdaddr);
1509
4e51eae9 1510 err = mgmt_event(MGMT_EV_DISCONNECTED, index, &ev, sizeof(ev), sk);
8962ee74
JH
1511
1512 if (sk)
1513 sock_put(sk);
1514
1515 return err;
1516}
1517
1518int mgmt_disconnect_failed(u16 index)
1519{
1520 struct pending_cmd *cmd;
1521 int err;
1522
1523 cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, index);
1524 if (!cmd)
1525 return -ENOENT;
1526
4e51eae9 1527 err = cmd_status(cmd->sk, index, MGMT_OP_DISCONNECT, EIO);
8962ee74 1528
a664b5bc 1529 mgmt_pending_remove(cmd);
8962ee74
JH
1530
1531 return err;
f7520543 1532}
17d5c04c
JH
1533
1534int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status)
1535{
1536 struct mgmt_ev_connect_failed ev;
1537
17d5c04c
JH
1538 bacpy(&ev.bdaddr, bdaddr);
1539 ev.status = status;
1540
4e51eae9 1541 return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL);
17d5c04c 1542}
980e1a53
JH
1543
1544int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr)
1545{
1546 struct mgmt_ev_pin_code_request ev;
1547
980e1a53
JH
1548 bacpy(&ev.bdaddr, bdaddr);
1549
4e51eae9
SJ
1550 return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev),
1551 NULL);
980e1a53
JH
1552}
1553
1554int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
1555{
1556 struct pending_cmd *cmd;
ac56fb13 1557 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
1558 int err;
1559
1560 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, index);
1561 if (!cmd)
1562 return -ENOENT;
1563
ac56fb13
JH
1564 bacpy(&rp.bdaddr, bdaddr);
1565 rp.status = status;
1566
4e51eae9
SJ
1567 err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_REPLY, &rp,
1568 sizeof(rp));
980e1a53 1569
a664b5bc 1570 mgmt_pending_remove(cmd);
980e1a53
JH
1571
1572 return err;
1573}
1574
1575int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
1576{
1577 struct pending_cmd *cmd;
ac56fb13 1578 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
1579 int err;
1580
1581 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, index);
1582 if (!cmd)
1583 return -ENOENT;
1584
ac56fb13
JH
1585 bacpy(&rp.bdaddr, bdaddr);
1586 rp.status = status;
1587
4e51eae9
SJ
1588 err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, &rp,
1589 sizeof(rp));
980e1a53 1590
a664b5bc 1591 mgmt_pending_remove(cmd);
980e1a53
JH
1592
1593 return err;
1594}
a5c29683
JH
1595
1596int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value)
1597{
1598 struct mgmt_ev_user_confirm_request ev;
1599
1600 BT_DBG("hci%u", index);
1601
a5c29683
JH
1602 bacpy(&ev.bdaddr, bdaddr);
1603 put_unaligned_le32(value, &ev.value);
1604
4e51eae9
SJ
1605 return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev),
1606 NULL);
a5c29683
JH
1607}
1608
1609static int confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status,
1610 u8 opcode)
1611{
1612 struct pending_cmd *cmd;
1613 struct mgmt_rp_user_confirm_reply rp;
1614 int err;
1615
1616 cmd = mgmt_pending_find(opcode, index);
1617 if (!cmd)
1618 return -ENOENT;
1619
a5c29683
JH
1620 bacpy(&rp.bdaddr, bdaddr);
1621 rp.status = status;
4e51eae9 1622 err = cmd_complete(cmd->sk, index, opcode, &rp, sizeof(rp));
a5c29683 1623
a664b5bc 1624 mgmt_pending_remove(cmd);
a5c29683
JH
1625
1626 return err;
1627}
1628
1629int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
1630{
1631 return confirm_reply_complete(index, bdaddr, status,
1632 MGMT_OP_USER_CONFIRM_REPLY);
1633}
1634
b8534e0f 1635int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
a5c29683
JH
1636{
1637 return confirm_reply_complete(index, bdaddr, status,
1638 MGMT_OP_USER_CONFIRM_NEG_REPLY);
1639}
2a611692
JH
1640
1641int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status)
1642{
1643 struct mgmt_ev_auth_failed ev;
1644
2a611692
JH
1645 bacpy(&ev.bdaddr, bdaddr);
1646 ev.status = status;
1647
4e51eae9 1648 return mgmt_event(MGMT_EV_AUTH_FAILED, index, &ev, sizeof(ev), NULL);
2a611692 1649}
This page took 0.126257 seconds and 5 git commands to generate.