]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - net/bluetooth/mgmt.c
Bluetooth: Add timeout field to mgmt_set_discoverable
[mirror_ubuntu-artful-kernel.git] / net / bluetooth / mgmt.c
CommitLineData
0381101f
JH
1/*
2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2010 Nokia Corporation
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation;
8
9 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20 SOFTWARE IS DISCLAIMED.
21*/
22
23/* Bluetooth HCI Management interface */
24
72359753 25#include <linux/uaccess.h>
0381101f
JH
26#include <asm/unaligned.h>
27
28#include <net/bluetooth/bluetooth.h>
29#include <net/bluetooth/hci_core.h>
30#include <net/bluetooth/mgmt.h>
31
02d98129
JH
32#define MGMT_VERSION 0
33#define MGMT_REVISION 1
34
2519a1fc
AG
35#define INQUIRY_LEN_BREDR 0x08 /* TGAP(100) */
36
eec8d2bc
JH
37struct pending_cmd {
38 struct list_head list;
39 __u16 opcode;
40 int index;
c68fb7ff 41 void *param;
eec8d2bc 42 struct sock *sk;
e9a416b5 43 void *user_data;
eec8d2bc
JH
44};
45
b5ad8b7f 46static LIST_HEAD(cmd_list);
eec8d2bc 47
4e51eae9 48static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
f7b64e69
JH
49{
50 struct sk_buff *skb;
51 struct mgmt_hdr *hdr;
52 struct mgmt_ev_cmd_status *ev;
56b7d137 53 int err;
f7b64e69 54
34eb525c 55 BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status);
f7b64e69
JH
56
57 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC);
58 if (!skb)
59 return -ENOMEM;
60
61 hdr = (void *) skb_put(skb, sizeof(*hdr));
62
63 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS);
4e51eae9 64 hdr->index = cpu_to_le16(index);
f7b64e69
JH
65 hdr->len = cpu_to_le16(sizeof(*ev));
66
67 ev = (void *) skb_put(skb, sizeof(*ev));
68 ev->status = status;
69 put_unaligned_le16(cmd, &ev->opcode);
70
56b7d137
GP
71 err = sock_queue_rcv_skb(sk, skb);
72 if (err < 0)
f7b64e69
JH
73 kfree_skb(skb);
74
56b7d137 75 return err;
f7b64e69
JH
76}
77
4e51eae9
SJ
78static int cmd_complete(struct sock *sk, u16 index, u16 cmd, void *rp,
79 size_t rp_len)
02d98129
JH
80{
81 struct sk_buff *skb;
82 struct mgmt_hdr *hdr;
83 struct mgmt_ev_cmd_complete *ev;
56b7d137 84 int err;
02d98129
JH
85
86 BT_DBG("sock %p", sk);
87
a38528f1 88 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_ATOMIC);
02d98129
JH
89 if (!skb)
90 return -ENOMEM;
91
92 hdr = (void *) skb_put(skb, sizeof(*hdr));
02d98129 93
a38528f1 94 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
4e51eae9 95 hdr->index = cpu_to_le16(index);
a38528f1 96 hdr->len = cpu_to_le16(sizeof(*ev) + rp_len);
02d98129 97
a38528f1
JH
98 ev = (void *) skb_put(skb, sizeof(*ev) + rp_len);
99 put_unaligned_le16(cmd, &ev->opcode);
8020c16a
SJ
100
101 if (rp)
102 memcpy(ev->data, rp, rp_len);
02d98129 103
56b7d137
GP
104 err = sock_queue_rcv_skb(sk, skb);
105 if (err < 0)
02d98129
JH
106 kfree_skb(skb);
107
56b7d137 108 return err;;
02d98129
JH
109}
110
a38528f1
JH
111static int read_version(struct sock *sk)
112{
113 struct mgmt_rp_read_version rp;
114
115 BT_DBG("sock %p", sk);
116
117 rp.version = MGMT_VERSION;
118 put_unaligned_le16(MGMT_REVISION, &rp.revision);
119
4e51eae9
SJ
120 return cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_VERSION, &rp,
121 sizeof(rp));
a38528f1
JH
122}
123
faba42eb
JH
124static int read_index_list(struct sock *sk)
125{
faba42eb
JH
126 struct mgmt_rp_read_index_list *rp;
127 struct list_head *p;
8035ded4 128 struct hci_dev *d;
a38528f1 129 size_t rp_len;
faba42eb 130 u16 count;
a38528f1 131 int i, err;
faba42eb
JH
132
133 BT_DBG("sock %p", sk);
134
135 read_lock(&hci_dev_list_lock);
136
137 count = 0;
138 list_for_each(p, &hci_dev_list) {
139 count++;
140 }
141
a38528f1
JH
142 rp_len = sizeof(*rp) + (2 * count);
143 rp = kmalloc(rp_len, GFP_ATOMIC);
144 if (!rp) {
b2c60d42 145 read_unlock(&hci_dev_list_lock);
faba42eb 146 return -ENOMEM;
b2c60d42 147 }
faba42eb 148
faba42eb
JH
149 put_unaligned_le16(count, &rp->num_controllers);
150
151 i = 0;
8035ded4 152 list_for_each_entry(d, &hci_dev_list, list) {
ab81cbf9
JH
153 hci_del_off_timer(d);
154
155 if (test_bit(HCI_SETUP, &d->flags))
156 continue;
157
faba42eb
JH
158 put_unaligned_le16(d->id, &rp->index[i++]);
159 BT_DBG("Added hci%u", d->id);
160 }
161
162 read_unlock(&hci_dev_list_lock);
163
4e51eae9
SJ
164 err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, rp,
165 rp_len);
faba42eb 166
a38528f1
JH
167 kfree(rp);
168
169 return err;
faba42eb
JH
170}
171
4e51eae9 172static int read_controller_info(struct sock *sk, u16 index)
0381101f 173{
a38528f1 174 struct mgmt_rp_read_info rp;
f7b64e69 175 struct hci_dev *hdev;
0381101f 176
4e51eae9 177 BT_DBG("sock %p hci%u", sk, index);
f7b64e69 178
4e51eae9 179 hdev = hci_dev_get(index);
a38528f1 180 if (!hdev)
4e51eae9 181 return cmd_status(sk, index, MGMT_OP_READ_INFO, ENODEV);
f7b64e69 182
ab81cbf9
JH
183 hci_del_off_timer(hdev);
184
8c156c32 185 hci_dev_lock_bh(hdev);
f7b64e69 186
ebc99feb
JH
187 set_bit(HCI_MGMT, &hdev->flags);
188
dc4fe30b
JH
189 memset(&rp, 0, sizeof(rp));
190
a38528f1 191 rp.type = hdev->dev_type;
f7b64e69 192
a38528f1
JH
193 rp.powered = test_bit(HCI_UP, &hdev->flags);
194 rp.connectable = test_bit(HCI_PSCAN, &hdev->flags);
195 rp.discoverable = test_bit(HCI_ISCAN, &hdev->flags);
196 rp.pairable = test_bit(HCI_PSCAN, &hdev->flags);
f7b64e69
JH
197
198 if (test_bit(HCI_AUTH, &hdev->flags))
a38528f1 199 rp.sec_mode = 3;
f7b64e69 200 else if (hdev->ssp_mode > 0)
a38528f1 201 rp.sec_mode = 4;
f7b64e69 202 else
a38528f1 203 rp.sec_mode = 2;
f7b64e69 204
a38528f1
JH
205 bacpy(&rp.bdaddr, &hdev->bdaddr);
206 memcpy(rp.features, hdev->features, 8);
207 memcpy(rp.dev_class, hdev->dev_class, 3);
208 put_unaligned_le16(hdev->manufacturer, &rp.manufacturer);
209 rp.hci_ver = hdev->hci_ver;
210 put_unaligned_le16(hdev->hci_rev, &rp.hci_rev);
f7b64e69 211
dc4fe30b
JH
212 memcpy(rp.name, hdev->dev_name, sizeof(hdev->dev_name));
213
8c156c32 214 hci_dev_unlock_bh(hdev);
f7b64e69 215 hci_dev_put(hdev);
0381101f 216
4e51eae9 217 return cmd_complete(sk, index, MGMT_OP_READ_INFO, &rp, sizeof(rp));
0381101f
JH
218}
219
eec8d2bc
JH
220static void mgmt_pending_free(struct pending_cmd *cmd)
221{
222 sock_put(cmd->sk);
c68fb7ff 223 kfree(cmd->param);
eec8d2bc
JH
224 kfree(cmd);
225}
226
366a0336
JH
227static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
228 u16 index, void *data, u16 len)
eec8d2bc
JH
229{
230 struct pending_cmd *cmd;
231
232 cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
233 if (!cmd)
366a0336 234 return NULL;
eec8d2bc
JH
235
236 cmd->opcode = opcode;
237 cmd->index = index;
238
c68fb7ff
SJ
239 cmd->param = kmalloc(len, GFP_ATOMIC);
240 if (!cmd->param) {
eec8d2bc 241 kfree(cmd);
366a0336 242 return NULL;
eec8d2bc
JH
243 }
244
8fce6357
SJ
245 if (data)
246 memcpy(cmd->param, data, len);
eec8d2bc
JH
247
248 cmd->sk = sk;
249 sock_hold(sk);
250
251 list_add(&cmd->list, &cmd_list);
252
366a0336 253 return cmd;
eec8d2bc
JH
254}
255
256static void mgmt_pending_foreach(u16 opcode, int index,
257 void (*cb)(struct pending_cmd *cmd, void *data),
258 void *data)
259{
260 struct list_head *p, *n;
261
262 list_for_each_safe(p, n, &cmd_list) {
263 struct pending_cmd *cmd;
264
265 cmd = list_entry(p, struct pending_cmd, list);
266
b24752fe 267 if (opcode > 0 && cmd->opcode != opcode)
eec8d2bc
JH
268 continue;
269
270 if (index >= 0 && cmd->index != index)
271 continue;
272
273 cb(cmd, data);
274 }
275}
276
277static struct pending_cmd *mgmt_pending_find(u16 opcode, int index)
278{
8035ded4 279 struct pending_cmd *cmd;
eec8d2bc 280
8035ded4 281 list_for_each_entry(cmd, &cmd_list, list) {
eec8d2bc
JH
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 317
8c156c32 318 hci_dev_lock_bh(hdev);
eec8d2bc
JH
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:
8c156c32 345 hci_dev_unlock_bh(hdev);
eec8d2bc 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{
16ab91ab 353 struct mgmt_cp_set_discoverable *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 369
8c156c32 370 hci_dev_lock_bh(hdev);
73f22f62
JH
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 398 scan |= SCAN_INQUIRY;
16ab91ab
JH
399 else
400 cancel_delayed_work_sync(&hdev->discov_off);
73f22f62
JH
401
402 err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
403 if (err < 0)
a664b5bc 404 mgmt_pending_remove(cmd);
73f22f62 405
16ab91ab
JH
406 if (cp->val)
407 hdev->discov_timeout = get_unaligned_le16(&cp->timeout);
408
73f22f62 409failed:
8c156c32 410 hci_dev_unlock_bh(hdev);
73f22f62
JH
411 hci_dev_put(hdev);
412
413 return err;
414}
415
4e51eae9
SJ
416static int set_connectable(struct sock *sk, u16 index, unsigned char *data,
417 u16 len)
9fbcbb45 418{
72a734ec 419 struct mgmt_mode *cp;
9fbcbb45 420 struct hci_dev *hdev;
366a0336 421 struct pending_cmd *cmd;
9fbcbb45
JH
422 u8 scan;
423 int err;
424
425 cp = (void *) data;
9fbcbb45 426
4e51eae9 427 BT_DBG("request for hci%u", index);
9fbcbb45 428
bdce7baf
SJ
429 if (len != sizeof(*cp))
430 return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EINVAL);
431
4e51eae9 432 hdev = hci_dev_get(index);
9fbcbb45 433 if (!hdev)
4e51eae9 434 return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENODEV);
9fbcbb45 435
8c156c32 436 hci_dev_lock_bh(hdev);
9fbcbb45
JH
437
438 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9 439 err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENETDOWN);
9fbcbb45
JH
440 goto failed;
441 }
442
4e51eae9
SJ
443 if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, index) ||
444 mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, index)) {
445 err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EBUSY);
9fbcbb45
JH
446 goto failed;
447 }
448
72a734ec 449 if (cp->val == test_bit(HCI_PSCAN, &hdev->flags)) {
4e51eae9 450 err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EALREADY);
9fbcbb45
JH
451 goto failed;
452 }
453
4e51eae9 454 cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, index, data, len);
366a0336
JH
455 if (!cmd) {
456 err = -ENOMEM;
9fbcbb45 457 goto failed;
366a0336 458 }
9fbcbb45 459
72a734ec 460 if (cp->val)
9fbcbb45
JH
461 scan = SCAN_PAGE;
462 else
463 scan = 0;
464
465 err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
466 if (err < 0)
a664b5bc 467 mgmt_pending_remove(cmd);
9fbcbb45
JH
468
469failed:
8c156c32 470 hci_dev_unlock_bh(hdev);
9fbcbb45
JH
471 hci_dev_put(hdev);
472
473 return err;
474}
475
4e51eae9
SJ
476static int mgmt_event(u16 event, u16 index, void *data, u16 data_len,
477 struct sock *skip_sk)
c542a06c
JH
478{
479 struct sk_buff *skb;
480 struct mgmt_hdr *hdr;
481
482 skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC);
483 if (!skb)
484 return -ENOMEM;
485
486 bt_cb(skb)->channel = HCI_CHANNEL_CONTROL;
487
488 hdr = (void *) skb_put(skb, sizeof(*hdr));
489 hdr->opcode = cpu_to_le16(event);
4e51eae9 490 hdr->index = cpu_to_le16(index);
c542a06c
JH
491 hdr->len = cpu_to_le16(data_len);
492
4e51eae9
SJ
493 if (data)
494 memcpy(skb_put(skb, data_len), data, data_len);
c542a06c
JH
495
496 hci_send_to_sock(NULL, skb, skip_sk);
497 kfree_skb(skb);
498
499 return 0;
500}
501
053f0211
JH
502static int send_mode_rsp(struct sock *sk, u16 opcode, u16 index, u8 val)
503{
a38528f1 504 struct mgmt_mode rp;
053f0211 505
a38528f1 506 rp.val = val;
053f0211 507
4e51eae9 508 return cmd_complete(sk, index, opcode, &rp, sizeof(rp));
053f0211
JH
509}
510
4e51eae9
SJ
511static int set_pairable(struct sock *sk, u16 index, unsigned char *data,
512 u16 len)
c542a06c
JH
513{
514 struct mgmt_mode *cp, ev;
515 struct hci_dev *hdev;
c542a06c
JH
516 int err;
517
518 cp = (void *) data;
c542a06c 519
4e51eae9 520 BT_DBG("request for hci%u", index);
c542a06c 521
bdce7baf
SJ
522 if (len != sizeof(*cp))
523 return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, EINVAL);
524
4e51eae9 525 hdev = hci_dev_get(index);
c542a06c 526 if (!hdev)
4e51eae9 527 return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, ENODEV);
c542a06c 528
8c156c32 529 hci_dev_lock_bh(hdev);
c542a06c
JH
530
531 if (cp->val)
532 set_bit(HCI_PAIRABLE, &hdev->flags);
533 else
534 clear_bit(HCI_PAIRABLE, &hdev->flags);
535
4e51eae9 536 err = send_mode_rsp(sk, MGMT_OP_SET_PAIRABLE, index, cp->val);
c542a06c
JH
537 if (err < 0)
538 goto failed;
539
c542a06c
JH
540 ev.val = cp->val;
541
4e51eae9 542 err = mgmt_event(MGMT_EV_PAIRABLE, index, &ev, sizeof(ev), sk);
c542a06c
JH
543
544failed:
8c156c32 545 hci_dev_unlock_bh(hdev);
c542a06c
JH
546 hci_dev_put(hdev);
547
548 return err;
549}
550
80a1e1db
JH
551#define EIR_FLAGS 0x01 /* flags */
552#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
553#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
554#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */
555#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
556#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */
557#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
558#define EIR_NAME_SHORT 0x08 /* shortened local name */
559#define EIR_NAME_COMPLETE 0x09 /* complete local name */
560#define EIR_TX_POWER 0x0A /* transmit power level */
561#define EIR_DEVICE_ID 0x10 /* device ID */
562
563#define PNP_INFO_SVCLASS_ID 0x1200
564
565static u8 bluetooth_base_uuid[] = {
566 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
567 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568};
569
570static u16 get_uuid16(u8 *uuid128)
571{
572 u32 val;
573 int i;
574
575 for (i = 0; i < 12; i++) {
576 if (bluetooth_base_uuid[i] != uuid128[i])
577 return 0;
578 }
579
580 memcpy(&val, &uuid128[12], 4);
581
582 val = le32_to_cpu(val);
583 if (val > 0xffff)
584 return 0;
585
586 return (u16) val;
587}
588
589static void create_eir(struct hci_dev *hdev, u8 *data)
590{
591 u8 *ptr = data;
592 u16 eir_len = 0;
593 u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)];
594 int i, truncated = 0;
8035ded4 595 struct bt_uuid *uuid;
80a1e1db
JH
596 size_t name_len;
597
598 name_len = strlen(hdev->dev_name);
599
600 if (name_len > 0) {
601 /* EIR Data type */
602 if (name_len > 48) {
603 name_len = 48;
604 ptr[1] = EIR_NAME_SHORT;
605 } else
606 ptr[1] = EIR_NAME_COMPLETE;
607
608 /* EIR Data length */
609 ptr[0] = name_len + 1;
610
611 memcpy(ptr + 2, hdev->dev_name, name_len);
612
613 eir_len += (name_len + 2);
614 ptr += (name_len + 2);
615 }
616
617 memset(uuid16_list, 0, sizeof(uuid16_list));
618
619 /* Group all UUID16 types */
8035ded4 620 list_for_each_entry(uuid, &hdev->uuids, list) {
80a1e1db
JH
621 u16 uuid16;
622
623 uuid16 = get_uuid16(uuid->uuid);
624 if (uuid16 == 0)
625 return;
626
627 if (uuid16 < 0x1100)
628 continue;
629
630 if (uuid16 == PNP_INFO_SVCLASS_ID)
631 continue;
632
633 /* Stop if not enough space to put next UUID */
634 if (eir_len + 2 + sizeof(u16) > HCI_MAX_EIR_LENGTH) {
635 truncated = 1;
636 break;
637 }
638
639 /* Check for duplicates */
640 for (i = 0; uuid16_list[i] != 0; i++)
641 if (uuid16_list[i] == uuid16)
642 break;
643
644 if (uuid16_list[i] == 0) {
645 uuid16_list[i] = uuid16;
646 eir_len += sizeof(u16);
647 }
648 }
649
650 if (uuid16_list[0] != 0) {
651 u8 *length = ptr;
652
653 /* EIR Data type */
654 ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL;
655
656 ptr += 2;
657 eir_len += 2;
658
659 for (i = 0; uuid16_list[i] != 0; i++) {
660 *ptr++ = (uuid16_list[i] & 0x00ff);
661 *ptr++ = (uuid16_list[i] & 0xff00) >> 8;
662 }
663
664 /* EIR Data length */
665 *length = (i * sizeof(u16)) + 1;
666 }
667}
668
669static int update_eir(struct hci_dev *hdev)
670{
671 struct hci_cp_write_eir cp;
672
673 if (!(hdev->features[6] & LMP_EXT_INQ))
674 return 0;
675
676 if (hdev->ssp_mode == 0)
677 return 0;
678
679 if (test_bit(HCI_SERVICE_CACHE, &hdev->flags))
680 return 0;
681
682 memset(&cp, 0, sizeof(cp));
683
684 create_eir(hdev, cp.data);
685
686 if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0)
687 return 0;
688
689 memcpy(hdev->eir, cp.data, sizeof(cp.data));
690
691 return hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
692}
693
1aff6f09
JH
694static u8 get_service_classes(struct hci_dev *hdev)
695{
12dc0743 696 struct bt_uuid *uuid;
1aff6f09
JH
697 u8 val = 0;
698
12dc0743 699 list_for_each_entry(uuid, &hdev->uuids, list)
1aff6f09 700 val |= uuid->svc_hint;
1aff6f09
JH
701
702 return val;
703}
704
705static int update_class(struct hci_dev *hdev)
706{
707 u8 cod[3];
708
709 BT_DBG("%s", hdev->name);
710
711 if (test_bit(HCI_SERVICE_CACHE, &hdev->flags))
712 return 0;
713
714 cod[0] = hdev->minor_class;
715 cod[1] = hdev->major_class;
716 cod[2] = get_service_classes(hdev);
717
718 if (memcmp(cod, hdev->dev_class, 3) == 0)
719 return 0;
720
721 return hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
722}
723
4e51eae9 724static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
2aeb9a1a
JH
725{
726 struct mgmt_cp_add_uuid *cp;
727 struct hci_dev *hdev;
728 struct bt_uuid *uuid;
2aeb9a1a
JH
729 int err;
730
731 cp = (void *) data;
2aeb9a1a 732
4e51eae9 733 BT_DBG("request for hci%u", index);
2aeb9a1a 734
bdce7baf
SJ
735 if (len != sizeof(*cp))
736 return cmd_status(sk, index, MGMT_OP_ADD_UUID, EINVAL);
737
4e51eae9 738 hdev = hci_dev_get(index);
2aeb9a1a 739 if (!hdev)
4e51eae9 740 return cmd_status(sk, index, MGMT_OP_ADD_UUID, ENODEV);
2aeb9a1a 741
8c156c32 742 hci_dev_lock_bh(hdev);
2aeb9a1a
JH
743
744 uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC);
745 if (!uuid) {
746 err = -ENOMEM;
747 goto failed;
748 }
749
750 memcpy(uuid->uuid, cp->uuid, 16);
1aff6f09 751 uuid->svc_hint = cp->svc_hint;
2aeb9a1a
JH
752
753 list_add(&uuid->list, &hdev->uuids);
754
1aff6f09
JH
755 err = update_class(hdev);
756 if (err < 0)
757 goto failed;
758
80a1e1db
JH
759 err = update_eir(hdev);
760 if (err < 0)
761 goto failed;
762
4e51eae9 763 err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, NULL, 0);
2aeb9a1a
JH
764
765failed:
8c156c32 766 hci_dev_unlock_bh(hdev);
2aeb9a1a
JH
767 hci_dev_put(hdev);
768
769 return err;
770}
771
4e51eae9 772static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
2aeb9a1a
JH
773{
774 struct list_head *p, *n;
779cb850 775 struct mgmt_cp_remove_uuid *cp;
2aeb9a1a
JH
776 struct hci_dev *hdev;
777 u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2aeb9a1a
JH
778 int err, found;
779
780 cp = (void *) data;
2aeb9a1a 781
4e51eae9 782 BT_DBG("request for hci%u", index);
2aeb9a1a 783
bdce7baf
SJ
784 if (len != sizeof(*cp))
785 return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, EINVAL);
786
4e51eae9 787 hdev = hci_dev_get(index);
2aeb9a1a 788 if (!hdev)
4e51eae9 789 return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENODEV);
2aeb9a1a 790
8c156c32 791 hci_dev_lock_bh(hdev);
2aeb9a1a
JH
792
793 if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) {
794 err = hci_uuids_clear(hdev);
795 goto unlock;
796 }
797
798 found = 0;
799
800 list_for_each_safe(p, n, &hdev->uuids) {
801 struct bt_uuid *match = list_entry(p, struct bt_uuid, list);
802
803 if (memcmp(match->uuid, cp->uuid, 16) != 0)
804 continue;
805
806 list_del(&match->list);
807 found++;
808 }
809
810 if (found == 0) {
4e51eae9 811 err = cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENOENT);
2aeb9a1a
JH
812 goto unlock;
813 }
814
1aff6f09
JH
815 err = update_class(hdev);
816 if (err < 0)
817 goto unlock;
818
80a1e1db
JH
819 err = update_eir(hdev);
820 if (err < 0)
821 goto unlock;
822
4e51eae9 823 err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0);
2aeb9a1a
JH
824
825unlock:
8c156c32 826 hci_dev_unlock_bh(hdev);
2aeb9a1a
JH
827 hci_dev_put(hdev);
828
829 return err;
830}
831
4e51eae9
SJ
832static int set_dev_class(struct sock *sk, u16 index, unsigned char *data,
833 u16 len)
1aff6f09
JH
834{
835 struct hci_dev *hdev;
836 struct mgmt_cp_set_dev_class *cp;
1aff6f09
JH
837 int err;
838
839 cp = (void *) data;
1aff6f09 840
4e51eae9 841 BT_DBG("request for hci%u", index);
1aff6f09 842
bdce7baf
SJ
843 if (len != sizeof(*cp))
844 return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, EINVAL);
845
4e51eae9 846 hdev = hci_dev_get(index);
1aff6f09 847 if (!hdev)
4e51eae9 848 return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, ENODEV);
1aff6f09 849
8c156c32 850 hci_dev_lock_bh(hdev);
1aff6f09
JH
851
852 hdev->major_class = cp->major;
853 hdev->minor_class = cp->minor;
854
855 err = update_class(hdev);
856
857 if (err == 0)
4e51eae9 858 err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, NULL, 0);
1aff6f09 859
8c156c32 860 hci_dev_unlock_bh(hdev);
1aff6f09
JH
861 hci_dev_put(hdev);
862
863 return err;
864}
865
4e51eae9
SJ
866static int set_service_cache(struct sock *sk, u16 index, unsigned char *data,
867 u16 len)
1aff6f09
JH
868{
869 struct hci_dev *hdev;
870 struct mgmt_cp_set_service_cache *cp;
1aff6f09
JH
871 int err;
872
873 cp = (void *) data;
1aff6f09 874
bdce7baf 875 if (len != sizeof(*cp))
b8534e0f 876 return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, EINVAL);
bdce7baf 877
4e51eae9 878 hdev = hci_dev_get(index);
1aff6f09 879 if (!hdev)
4e51eae9 880 return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, ENODEV);
1aff6f09 881
8c156c32 882 hci_dev_lock_bh(hdev);
1aff6f09 883
4e51eae9 884 BT_DBG("hci%u enable %d", index, cp->enable);
1aff6f09
JH
885
886 if (cp->enable) {
887 set_bit(HCI_SERVICE_CACHE, &hdev->flags);
888 err = 0;
889 } else {
890 clear_bit(HCI_SERVICE_CACHE, &hdev->flags);
891 err = update_class(hdev);
80a1e1db
JH
892 if (err == 0)
893 err = update_eir(hdev);
1aff6f09
JH
894 }
895
896 if (err == 0)
4e51eae9
SJ
897 err = cmd_complete(sk, index, MGMT_OP_SET_SERVICE_CACHE, NULL,
898 0);
e5b82e58
GP
899 else
900 cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, -err);
901
1aff6f09 902
8c156c32 903 hci_dev_unlock_bh(hdev);
1aff6f09
JH
904 hci_dev_put(hdev);
905
906 return err;
907}
908
4e51eae9 909static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
55ed8ca1
JH
910{
911 struct hci_dev *hdev;
912 struct mgmt_cp_load_keys *cp;
4e51eae9 913 u16 key_count, expected_len;
a492cd52 914 int i;
55ed8ca1
JH
915
916 cp = (void *) data;
bdce7baf
SJ
917
918 if (len < sizeof(*cp))
b7059136 919 return cmd_status(sk, index, MGMT_OP_LOAD_KEYS, EINVAL);
bdce7baf 920
55ed8ca1
JH
921 key_count = get_unaligned_le16(&cp->key_count);
922
923 expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info);
a492cd52
VCG
924 if (expected_len != len) {
925 BT_ERR("load_keys: expected %u bytes, got %u bytes",
926 len, expected_len);
b7059136 927 return cmd_status(sk, index, MGMT_OP_LOAD_KEYS, EINVAL);
55ed8ca1
JH
928 }
929
4e51eae9 930 hdev = hci_dev_get(index);
55ed8ca1 931 if (!hdev)
4e51eae9 932 return cmd_status(sk, index, MGMT_OP_LOAD_KEYS, ENODEV);
55ed8ca1 933
4e51eae9 934 BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys,
55ed8ca1
JH
935 key_count);
936
8c156c32 937 hci_dev_lock_bh(hdev);
55ed8ca1
JH
938
939 hci_link_keys_clear(hdev);
940
941 set_bit(HCI_LINK_KEYS, &hdev->flags);
942
943 if (cp->debug_keys)
944 set_bit(HCI_DEBUG_KEYS, &hdev->flags);
945 else
946 clear_bit(HCI_DEBUG_KEYS, &hdev->flags);
947
a492cd52
VCG
948 for (i = 0; i < key_count; i++) {
949 struct mgmt_key_info *key = &cp->keys[i];
55ed8ca1 950
d25e28ab 951 hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type,
55ed8ca1
JH
952 key->pin_len);
953 }
954
8c156c32 955 hci_dev_unlock_bh(hdev);
55ed8ca1
JH
956 hci_dev_put(hdev);
957
a492cd52 958 return 0;
55ed8ca1
JH
959}
960
4e51eae9 961static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len)
55ed8ca1
JH
962{
963 struct hci_dev *hdev;
964 struct mgmt_cp_remove_key *cp;
965 struct hci_conn *conn;
55ed8ca1
JH
966 int err;
967
968 cp = (void *) data;
55ed8ca1 969
bdce7baf
SJ
970 if (len != sizeof(*cp))
971 return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, EINVAL);
972
4e51eae9 973 hdev = hci_dev_get(index);
55ed8ca1 974 if (!hdev)
4e51eae9 975 return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, ENODEV);
55ed8ca1 976
8c156c32 977 hci_dev_lock_bh(hdev);
55ed8ca1
JH
978
979 err = hci_remove_link_key(hdev, &cp->bdaddr);
980 if (err < 0) {
4e51eae9 981 err = cmd_status(sk, index, MGMT_OP_REMOVE_KEY, -err);
55ed8ca1
JH
982 goto unlock;
983 }
984
985 err = 0;
986
987 if (!test_bit(HCI_UP, &hdev->flags) || !cp->disconnect)
988 goto unlock;
989
990 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
991 if (conn) {
992 struct hci_cp_disconnect dc;
993
994 put_unaligned_le16(conn->handle, &dc.handle);
995 dc.reason = 0x13; /* Remote User Terminated Connection */
94ac0272 996 err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc);
55ed8ca1
JH
997 }
998
999unlock:
8c156c32 1000 hci_dev_unlock_bh(hdev);
55ed8ca1
JH
1001 hci_dev_put(hdev);
1002
1003 return err;
1004}
1005
4e51eae9 1006static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len)
8962ee74
JH
1007{
1008 struct hci_dev *hdev;
1009 struct mgmt_cp_disconnect *cp;
1010 struct hci_cp_disconnect dc;
366a0336 1011 struct pending_cmd *cmd;
8962ee74 1012 struct hci_conn *conn;
8962ee74
JH
1013 int err;
1014
1015 BT_DBG("");
1016
1017 cp = (void *) data;
8962ee74 1018
bdce7baf
SJ
1019 if (len != sizeof(*cp))
1020 return cmd_status(sk, index, MGMT_OP_DISCONNECT, EINVAL);
1021
4e51eae9 1022 hdev = hci_dev_get(index);
8962ee74 1023 if (!hdev)
4e51eae9 1024 return cmd_status(sk, index, MGMT_OP_DISCONNECT, ENODEV);
8962ee74 1025
8c156c32 1026 hci_dev_lock_bh(hdev);
8962ee74
JH
1027
1028 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9 1029 err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENETDOWN);
8962ee74
JH
1030 goto failed;
1031 }
1032
4e51eae9
SJ
1033 if (mgmt_pending_find(MGMT_OP_DISCONNECT, index)) {
1034 err = cmd_status(sk, index, MGMT_OP_DISCONNECT, EBUSY);
8962ee74
JH
1035 goto failed;
1036 }
1037
1038 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
365227e5
VCG
1039 if (!conn)
1040 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->bdaddr);
1041
8962ee74 1042 if (!conn) {
4e51eae9 1043 err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENOTCONN);
8962ee74
JH
1044 goto failed;
1045 }
1046
4e51eae9 1047 cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, index, data, len);
366a0336
JH
1048 if (!cmd) {
1049 err = -ENOMEM;
8962ee74 1050 goto failed;
366a0336 1051 }
8962ee74
JH
1052
1053 put_unaligned_le16(conn->handle, &dc.handle);
1054 dc.reason = 0x13; /* Remote User Terminated Connection */
1055
1056 err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc);
1057 if (err < 0)
a664b5bc 1058 mgmt_pending_remove(cmd);
8962ee74
JH
1059
1060failed:
8c156c32 1061 hci_dev_unlock_bh(hdev);
8962ee74
JH
1062 hci_dev_put(hdev);
1063
1064 return err;
1065}
1066
8ce6284e 1067static int get_connections(struct sock *sk, u16 index)
2784eb41 1068{
2784eb41
JH
1069 struct mgmt_rp_get_connections *rp;
1070 struct hci_dev *hdev;
8035ded4 1071 struct hci_conn *c;
2784eb41 1072 struct list_head *p;
a38528f1 1073 size_t rp_len;
4e51eae9 1074 u16 count;
2784eb41
JH
1075 int i, err;
1076
1077 BT_DBG("");
1078
4e51eae9 1079 hdev = hci_dev_get(index);
2784eb41 1080 if (!hdev)
4e51eae9 1081 return cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS, ENODEV);
2784eb41 1082
8c156c32 1083 hci_dev_lock_bh(hdev);
2784eb41
JH
1084
1085 count = 0;
1086 list_for_each(p, &hdev->conn_hash.list) {
1087 count++;
1088 }
1089
a38528f1
JH
1090 rp_len = sizeof(*rp) + (count * sizeof(bdaddr_t));
1091 rp = kmalloc(rp_len, GFP_ATOMIC);
1092 if (!rp) {
2784eb41
JH
1093 err = -ENOMEM;
1094 goto unlock;
1095 }
1096
2784eb41
JH
1097 put_unaligned_le16(count, &rp->conn_count);
1098
2784eb41 1099 i = 0;
8035ded4 1100 list_for_each_entry(c, &hdev->conn_hash.list, list)
2784eb41 1101 bacpy(&rp->conn[i++], &c->dst);
2784eb41 1102
4e51eae9 1103 err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len);
2784eb41
JH
1104
1105unlock:
a38528f1 1106 kfree(rp);
8c156c32 1107 hci_dev_unlock_bh(hdev);
2784eb41
JH
1108 hci_dev_put(hdev);
1109 return err;
1110}
1111
96d97a67
WR
1112static int send_pin_code_neg_reply(struct sock *sk, u16 index,
1113 struct hci_dev *hdev, struct mgmt_cp_pin_code_neg_reply *cp)
1114{
1115 struct pending_cmd *cmd;
1116 int err;
1117
1118 cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, index, cp,
1119 sizeof(*cp));
1120 if (!cmd)
1121 return -ENOMEM;
1122
1123 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(cp->bdaddr),
1124 &cp->bdaddr);
1125 if (err < 0)
1126 mgmt_pending_remove(cmd);
1127
1128 return err;
1129}
1130
4e51eae9
SJ
1131static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data,
1132 u16 len)
980e1a53
JH
1133{
1134 struct hci_dev *hdev;
96d97a67 1135 struct hci_conn *conn;
980e1a53 1136 struct mgmt_cp_pin_code_reply *cp;
96d97a67 1137 struct mgmt_cp_pin_code_neg_reply ncp;
980e1a53 1138 struct hci_cp_pin_code_reply reply;
366a0336 1139 struct pending_cmd *cmd;
980e1a53
JH
1140 int err;
1141
1142 BT_DBG("");
1143
1144 cp = (void *) data;
980e1a53 1145
bdce7baf
SJ
1146 if (len != sizeof(*cp))
1147 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, EINVAL);
1148
4e51eae9 1149 hdev = hci_dev_get(index);
980e1a53 1150 if (!hdev)
4e51eae9 1151 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENODEV);
980e1a53 1152
8c156c32 1153 hci_dev_lock_bh(hdev);
980e1a53
JH
1154
1155 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9 1156 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENETDOWN);
980e1a53
JH
1157 goto failed;
1158 }
1159
96d97a67
WR
1160 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1161 if (!conn) {
1162 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENOTCONN);
1163 goto failed;
1164 }
1165
1166 if (conn->pending_sec_level == BT_SECURITY_HIGH && cp->pin_len != 16) {
1167 bacpy(&ncp.bdaddr, &cp->bdaddr);
1168
1169 BT_ERR("PIN code is not 16 bytes long");
1170
1171 err = send_pin_code_neg_reply(sk, index, hdev, &ncp);
1172 if (err >= 0)
1173 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1174 EINVAL);
1175
1176 goto failed;
1177 }
1178
4e51eae9 1179 cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, index, data, len);
366a0336
JH
1180 if (!cmd) {
1181 err = -ENOMEM;
980e1a53 1182 goto failed;
366a0336 1183 }
980e1a53
JH
1184
1185 bacpy(&reply.bdaddr, &cp->bdaddr);
1186 reply.pin_len = cp->pin_len;
24718ca5 1187 memcpy(reply.pin_code, cp->pin_code, sizeof(reply.pin_code));
980e1a53
JH
1188
1189 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_REPLY, sizeof(reply), &reply);
1190 if (err < 0)
a664b5bc 1191 mgmt_pending_remove(cmd);
980e1a53
JH
1192
1193failed:
8c156c32 1194 hci_dev_unlock_bh(hdev);
980e1a53
JH
1195 hci_dev_put(hdev);
1196
1197 return err;
1198}
1199
4e51eae9
SJ
1200static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data,
1201 u16 len)
980e1a53
JH
1202{
1203 struct hci_dev *hdev;
1204 struct mgmt_cp_pin_code_neg_reply *cp;
980e1a53
JH
1205 int err;
1206
1207 BT_DBG("");
1208
1209 cp = (void *) data;
980e1a53 1210
bdce7baf
SJ
1211 if (len != sizeof(*cp))
1212 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
1213 EINVAL);
1214
4e51eae9 1215 hdev = hci_dev_get(index);
980e1a53 1216 if (!hdev)
4e51eae9
SJ
1217 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
1218 ENODEV);
980e1a53 1219
8c156c32 1220 hci_dev_lock_bh(hdev);
980e1a53
JH
1221
1222 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9
SJ
1223 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
1224 ENETDOWN);
980e1a53
JH
1225 goto failed;
1226 }
1227
96d97a67 1228 err = send_pin_code_neg_reply(sk, index, hdev, cp);
980e1a53
JH
1229
1230failed:
8c156c32 1231 hci_dev_unlock_bh(hdev);
980e1a53
JH
1232 hci_dev_put(hdev);
1233
1234 return err;
1235}
1236
4e51eae9
SJ
1237static int set_io_capability(struct sock *sk, u16 index, unsigned char *data,
1238 u16 len)
17fa4b9d
JH
1239{
1240 struct hci_dev *hdev;
1241 struct mgmt_cp_set_io_capability *cp;
17fa4b9d
JH
1242
1243 BT_DBG("");
1244
1245 cp = (void *) data;
17fa4b9d 1246
bdce7baf 1247 if (len != sizeof(*cp))
b8534e0f 1248 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, EINVAL);
bdce7baf 1249
4e51eae9 1250 hdev = hci_dev_get(index);
17fa4b9d 1251 if (!hdev)
4e51eae9 1252 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, ENODEV);
17fa4b9d 1253
8c156c32 1254 hci_dev_lock_bh(hdev);
17fa4b9d
JH
1255
1256 hdev->io_capability = cp->io_capability;
1257
1258 BT_DBG("%s IO capability set to 0x%02x", hdev->name,
b8534e0f 1259 hdev->io_capability);
17fa4b9d 1260
8c156c32 1261 hci_dev_unlock_bh(hdev);
17fa4b9d
JH
1262 hci_dev_put(hdev);
1263
4e51eae9 1264 return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, NULL, 0);
17fa4b9d
JH
1265}
1266
e9a416b5
JH
1267static inline struct pending_cmd *find_pairing(struct hci_conn *conn)
1268{
1269 struct hci_dev *hdev = conn->hdev;
8035ded4 1270 struct pending_cmd *cmd;
e9a416b5 1271
8035ded4 1272 list_for_each_entry(cmd, &cmd_list, list) {
e9a416b5
JH
1273 if (cmd->opcode != MGMT_OP_PAIR_DEVICE)
1274 continue;
1275
1276 if (cmd->index != hdev->id)
1277 continue;
1278
1279 if (cmd->user_data != conn)
1280 continue;
1281
1282 return cmd;
1283 }
1284
1285 return NULL;
1286}
1287
1288static void pairing_complete(struct pending_cmd *cmd, u8 status)
1289{
1290 struct mgmt_rp_pair_device rp;
1291 struct hci_conn *conn = cmd->user_data;
1292
e9a416b5
JH
1293 bacpy(&rp.bdaddr, &conn->dst);
1294 rp.status = status;
1295
4e51eae9 1296 cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, &rp, sizeof(rp));
e9a416b5
JH
1297
1298 /* So we don't get further callbacks for this connection */
1299 conn->connect_cfm_cb = NULL;
1300 conn->security_cfm_cb = NULL;
1301 conn->disconn_cfm_cb = NULL;
1302
1303 hci_conn_put(conn);
1304
a664b5bc 1305 mgmt_pending_remove(cmd);
e9a416b5
JH
1306}
1307
1308static void pairing_complete_cb(struct hci_conn *conn, u8 status)
1309{
1310 struct pending_cmd *cmd;
1311
1312 BT_DBG("status %u", status);
1313
1314 cmd = find_pairing(conn);
1315 if (!cmd) {
1316 BT_DBG("Unable to find a pending command");
1317 return;
1318 }
1319
1320 pairing_complete(cmd, status);
1321}
1322
4e51eae9 1323static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len)
e9a416b5
JH
1324{
1325 struct hci_dev *hdev;
1326 struct mgmt_cp_pair_device *cp;
1327 struct pending_cmd *cmd;
7a512d01 1328 struct adv_entry *entry;
e9a416b5
JH
1329 u8 sec_level, auth_type;
1330 struct hci_conn *conn;
e9a416b5
JH
1331 int err;
1332
1333 BT_DBG("");
1334
1335 cp = (void *) data;
e9a416b5 1336
bdce7baf
SJ
1337 if (len != sizeof(*cp))
1338 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, EINVAL);
1339
4e51eae9 1340 hdev = hci_dev_get(index);
e9a416b5 1341 if (!hdev)
4e51eae9 1342 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, ENODEV);
e9a416b5 1343
8c156c32 1344 hci_dev_lock_bh(hdev);
e9a416b5 1345
c908df36
VCG
1346 sec_level = BT_SECURITY_MEDIUM;
1347 if (cp->io_cap == 0x03)
e9a416b5 1348 auth_type = HCI_AT_DEDICATED_BONDING;
c908df36 1349 else
e9a416b5 1350 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
e9a416b5 1351
7a512d01
VCG
1352 entry = hci_find_adv_entry(hdev, &cp->bdaddr);
1353 if (entry)
1354 conn = hci_connect(hdev, LE_LINK, &cp->bdaddr, sec_level,
1355 auth_type);
1356 else
1357 conn = hci_connect(hdev, ACL_LINK, &cp->bdaddr, sec_level,
1358 auth_type);
1359
30e76272
VT
1360 if (IS_ERR(conn)) {
1361 err = PTR_ERR(conn);
e9a416b5
JH
1362 goto unlock;
1363 }
1364
1365 if (conn->connect_cfm_cb) {
1366 hci_conn_put(conn);
4e51eae9 1367 err = cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, EBUSY);
e9a416b5
JH
1368 goto unlock;
1369 }
1370
4e51eae9 1371 cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, index, data, len);
e9a416b5
JH
1372 if (!cmd) {
1373 err = -ENOMEM;
1374 hci_conn_put(conn);
1375 goto unlock;
1376 }
1377
7a512d01
VCG
1378 /* For LE, just connecting isn't a proof that the pairing finished */
1379 if (!entry)
1380 conn->connect_cfm_cb = pairing_complete_cb;
1381
e9a416b5
JH
1382 conn->security_cfm_cb = pairing_complete_cb;
1383 conn->disconn_cfm_cb = pairing_complete_cb;
1384 conn->io_capability = cp->io_cap;
1385 cmd->user_data = conn;
1386
1387 if (conn->state == BT_CONNECTED &&
1388 hci_conn_security(conn, sec_level, auth_type))
1389 pairing_complete(cmd, 0);
1390
1391 err = 0;
1392
1393unlock:
8c156c32 1394 hci_dev_unlock_bh(hdev);
e9a416b5
JH
1395 hci_dev_put(hdev);
1396
1397 return err;
1398}
1399
4e51eae9
SJ
1400static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data,
1401 u16 len, int success)
a5c29683
JH
1402{
1403 struct mgmt_cp_user_confirm_reply *cp = (void *) data;
4e51eae9 1404 u16 mgmt_op, hci_op;
a5c29683
JH
1405 struct pending_cmd *cmd;
1406 struct hci_dev *hdev;
1407 int err;
1408
1409 BT_DBG("");
1410
a5c29683
JH
1411 if (success) {
1412 mgmt_op = MGMT_OP_USER_CONFIRM_REPLY;
1413 hci_op = HCI_OP_USER_CONFIRM_REPLY;
1414 } else {
1415 mgmt_op = MGMT_OP_USER_CONFIRM_NEG_REPLY;
1416 hci_op = HCI_OP_USER_CONFIRM_NEG_REPLY;
1417 }
1418
bdce7baf
SJ
1419 if (len != sizeof(*cp))
1420 return cmd_status(sk, index, mgmt_op, EINVAL);
1421
4e51eae9 1422 hdev = hci_dev_get(index);
a5c29683 1423 if (!hdev)
4e51eae9 1424 return cmd_status(sk, index, mgmt_op, ENODEV);
a5c29683 1425
8c156c32 1426 hci_dev_lock_bh(hdev);
08ba5382 1427
a5c29683 1428 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9 1429 err = cmd_status(sk, index, mgmt_op, ENETDOWN);
a5c29683
JH
1430 goto failed;
1431 }
1432
4e51eae9 1433 cmd = mgmt_pending_add(sk, mgmt_op, index, data, len);
a5c29683
JH
1434 if (!cmd) {
1435 err = -ENOMEM;
1436 goto failed;
1437 }
1438
1439 err = hci_send_cmd(hdev, hci_op, sizeof(cp->bdaddr), &cp->bdaddr);
a664b5bc
JH
1440 if (err < 0)
1441 mgmt_pending_remove(cmd);
a5c29683
JH
1442
1443failed:
8c156c32 1444 hci_dev_unlock_bh(hdev);
a5c29683
JH
1445 hci_dev_put(hdev);
1446
1447 return err;
1448}
1449
b312b161
JH
1450static int set_local_name(struct sock *sk, u16 index, unsigned char *data,
1451 u16 len)
1452{
1453 struct mgmt_cp_set_local_name *mgmt_cp = (void *) data;
1454 struct hci_cp_write_local_name hci_cp;
1455 struct hci_dev *hdev;
1456 struct pending_cmd *cmd;
1457 int err;
1458
1459 BT_DBG("");
1460
1461 if (len != sizeof(*mgmt_cp))
1462 return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME, EINVAL);
1463
1464 hdev = hci_dev_get(index);
1465 if (!hdev)
1466 return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME, ENODEV);
1467
8c156c32 1468 hci_dev_lock_bh(hdev);
b312b161
JH
1469
1470 cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, index, data, len);
1471 if (!cmd) {
1472 err = -ENOMEM;
1473 goto failed;
1474 }
1475
1476 memcpy(hci_cp.name, mgmt_cp->name, sizeof(hci_cp.name));
1477 err = hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(hci_cp),
1478 &hci_cp);
1479 if (err < 0)
1480 mgmt_pending_remove(cmd);
1481
1482failed:
8c156c32 1483 hci_dev_unlock_bh(hdev);
b312b161
JH
1484 hci_dev_put(hdev);
1485
1486 return err;
1487}
1488
c35938b2
SJ
1489static int read_local_oob_data(struct sock *sk, u16 index)
1490{
1491 struct hci_dev *hdev;
1492 struct pending_cmd *cmd;
1493 int err;
1494
1495 BT_DBG("hci%u", index);
1496
1497 hdev = hci_dev_get(index);
1498 if (!hdev)
1499 return cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
1500 ENODEV);
1501
8c156c32 1502 hci_dev_lock_bh(hdev);
c35938b2
SJ
1503
1504 if (!test_bit(HCI_UP, &hdev->flags)) {
1505 err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
1506 ENETDOWN);
1507 goto unlock;
1508 }
1509
1510 if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) {
1511 err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
1512 EOPNOTSUPP);
1513 goto unlock;
1514 }
1515
1516 if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index)) {
1517 err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, EBUSY);
1518 goto unlock;
1519 }
1520
1521 cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, index, NULL, 0);
1522 if (!cmd) {
1523 err = -ENOMEM;
1524 goto unlock;
1525 }
1526
1527 err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
1528 if (err < 0)
1529 mgmt_pending_remove(cmd);
1530
1531unlock:
8c156c32 1532 hci_dev_unlock_bh(hdev);
c35938b2
SJ
1533 hci_dev_put(hdev);
1534
1535 return err;
1536}
1537
2763eda6
SJ
1538static int add_remote_oob_data(struct sock *sk, u16 index, unsigned char *data,
1539 u16 len)
1540{
1541 struct hci_dev *hdev;
1542 struct mgmt_cp_add_remote_oob_data *cp = (void *) data;
1543 int err;
1544
1545 BT_DBG("hci%u ", index);
1546
1547 if (len != sizeof(*cp))
1548 return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
1549 EINVAL);
1550
1551 hdev = hci_dev_get(index);
1552 if (!hdev)
1553 return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
1554 ENODEV);
1555
8c156c32 1556 hci_dev_lock_bh(hdev);
2763eda6
SJ
1557
1558 err = hci_add_remote_oob_data(hdev, &cp->bdaddr, cp->hash,
1559 cp->randomizer);
1560 if (err < 0)
1561 err = cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, -err);
1562 else
1563 err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, NULL,
1564 0);
1565
8c156c32 1566 hci_dev_unlock_bh(hdev);
2763eda6
SJ
1567 hci_dev_put(hdev);
1568
1569 return err;
1570}
1571
1572static int remove_remote_oob_data(struct sock *sk, u16 index,
1573 unsigned char *data, u16 len)
1574{
1575 struct hci_dev *hdev;
1576 struct mgmt_cp_remove_remote_oob_data *cp = (void *) data;
1577 int err;
1578
1579 BT_DBG("hci%u ", index);
1580
1581 if (len != sizeof(*cp))
1582 return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
1583 EINVAL);
1584
1585 hdev = hci_dev_get(index);
1586 if (!hdev)
1587 return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
1588 ENODEV);
1589
8c156c32 1590 hci_dev_lock_bh(hdev);
2763eda6
SJ
1591
1592 err = hci_remove_remote_oob_data(hdev, &cp->bdaddr);
1593 if (err < 0)
1594 err = cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
1595 -err);
1596 else
1597 err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
1598 NULL, 0);
1599
8c156c32 1600 hci_dev_unlock_bh(hdev);
2763eda6
SJ
1601 hci_dev_put(hdev);
1602
1603 return err;
1604}
1605
14a53664
JH
1606static int start_discovery(struct sock *sk, u16 index)
1607{
14a53664
JH
1608 struct pending_cmd *cmd;
1609 struct hci_dev *hdev;
1610 int err;
1611
1612 BT_DBG("hci%u", index);
1613
1614 hdev = hci_dev_get(index);
1615 if (!hdev)
1616 return cmd_status(sk, index, MGMT_OP_START_DISCOVERY, ENODEV);
1617
1618 hci_dev_lock_bh(hdev);
1619
1620 cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, index, NULL, 0);
1621 if (!cmd) {
1622 err = -ENOMEM;
1623 goto failed;
1624 }
1625
2519a1fc 1626 err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR);
14a53664
JH
1627 if (err < 0)
1628 mgmt_pending_remove(cmd);
1629
1630failed:
1631 hci_dev_unlock_bh(hdev);
1632 hci_dev_put(hdev);
1633
1634 return err;
1635}
1636
1637static int stop_discovery(struct sock *sk, u16 index)
1638{
1639 struct hci_dev *hdev;
1640 struct pending_cmd *cmd;
1641 int err;
1642
1643 BT_DBG("hci%u", index);
1644
1645 hdev = hci_dev_get(index);
1646 if (!hdev)
1647 return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY, ENODEV);
1648
1649 hci_dev_lock_bh(hdev);
1650
1651 cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, index, NULL, 0);
1652 if (!cmd) {
1653 err = -ENOMEM;
1654 goto failed;
1655 }
1656
023d5049 1657 err = hci_cancel_inquiry(hdev);
14a53664
JH
1658 if (err < 0)
1659 mgmt_pending_remove(cmd);
1660
1661failed:
1662 hci_dev_unlock_bh(hdev);
1663 hci_dev_put(hdev);
1664
1665 return err;
1666}
1667
7fbec224
AJ
1668static int block_device(struct sock *sk, u16 index, unsigned char *data,
1669 u16 len)
1670{
1671 struct hci_dev *hdev;
5e762444
AJ
1672 struct pending_cmd *cmd;
1673 struct mgmt_cp_block_device *cp = (void *) data;
7fbec224
AJ
1674 int err;
1675
1676 BT_DBG("hci%u", index);
1677
7fbec224
AJ
1678 if (len != sizeof(*cp))
1679 return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
1680 EINVAL);
1681
1682 hdev = hci_dev_get(index);
1683 if (!hdev)
1684 return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
1685 ENODEV);
1686
5e762444
AJ
1687 hci_dev_lock_bh(hdev);
1688
1689 cmd = mgmt_pending_add(sk, MGMT_OP_BLOCK_DEVICE, index, NULL, 0);
1690 if (!cmd) {
1691 err = -ENOMEM;
1692 goto failed;
1693 }
1694
7fbec224
AJ
1695 err = hci_blacklist_add(hdev, &cp->bdaddr);
1696
1697 if (err < 0)
1698 err = cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, -err);
1699 else
1700 err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE,
1701 NULL, 0);
5e762444
AJ
1702
1703 mgmt_pending_remove(cmd);
1704
1705failed:
1706 hci_dev_unlock_bh(hdev);
7fbec224
AJ
1707 hci_dev_put(hdev);
1708
1709 return err;
1710}
1711
1712static int unblock_device(struct sock *sk, u16 index, unsigned char *data,
1713 u16 len)
1714{
1715 struct hci_dev *hdev;
5e762444
AJ
1716 struct pending_cmd *cmd;
1717 struct mgmt_cp_unblock_device *cp = (void *) data;
7fbec224
AJ
1718 int err;
1719
1720 BT_DBG("hci%u", index);
1721
7fbec224
AJ
1722 if (len != sizeof(*cp))
1723 return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
1724 EINVAL);
1725
1726 hdev = hci_dev_get(index);
1727 if (!hdev)
1728 return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
1729 ENODEV);
1730
5e762444
AJ
1731 hci_dev_lock_bh(hdev);
1732
1733 cmd = mgmt_pending_add(sk, MGMT_OP_UNBLOCK_DEVICE, index, NULL, 0);
1734 if (!cmd) {
1735 err = -ENOMEM;
1736 goto failed;
1737 }
1738
7fbec224
AJ
1739 err = hci_blacklist_del(hdev, &cp->bdaddr);
1740
1741 if (err < 0)
1742 err = cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE, -err);
1743 else
1744 err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE,
1745 NULL, 0);
5e762444
AJ
1746
1747 mgmt_pending_remove(cmd);
1748
1749failed:
1750 hci_dev_unlock_bh(hdev);
7fbec224
AJ
1751 hci_dev_put(hdev);
1752
1753 return err;
1754}
1755
f6422ec6
AJ
1756static int set_fast_connectable(struct sock *sk, u16 index,
1757 unsigned char *data, u16 len)
1758{
1759 struct hci_dev *hdev;
1760 struct mgmt_cp_set_fast_connectable *cp = (void *) data;
1761 struct hci_cp_write_page_scan_activity acp;
1762 u8 type;
1763 int err;
1764
1765 BT_DBG("hci%u", index);
1766
1767 if (len != sizeof(*cp))
1768 return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
1769 EINVAL);
1770
1771 hdev = hci_dev_get(index);
1772 if (!hdev)
1773 return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
1774 ENODEV);
1775
1776 hci_dev_lock(hdev);
1777
1778 if (cp->enable) {
1779 type = PAGE_SCAN_TYPE_INTERLACED;
1780 acp.interval = 0x0024; /* 22.5 msec page scan interval */
1781 } else {
1782 type = PAGE_SCAN_TYPE_STANDARD; /* default */
1783 acp.interval = 0x0800; /* default 1.28 sec page scan */
1784 }
1785
1786 acp.window = 0x0012; /* default 11.25 msec page scan window */
1787
1788 err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
1789 sizeof(acp), &acp);
1790 if (err < 0) {
1791 err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
1792 -err);
1793 goto done;
1794 }
1795
1796 err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type);
1797 if (err < 0) {
1798 err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
1799 -err);
1800 goto done;
1801 }
1802
1803 err = cmd_complete(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
1804 NULL, 0);
1805done:
1806 hci_dev_unlock(hdev);
1807 hci_dev_put(hdev);
1808
1809 return err;
1810}
1811
0381101f
JH
1812int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
1813{
1814 unsigned char *buf;
1815 struct mgmt_hdr *hdr;
4e51eae9 1816 u16 opcode, index, len;
0381101f
JH
1817 int err;
1818
1819 BT_DBG("got %zu bytes", msglen);
1820
1821 if (msglen < sizeof(*hdr))
1822 return -EINVAL;
1823
e63a15ec 1824 buf = kmalloc(msglen, GFP_KERNEL);
0381101f
JH
1825 if (!buf)
1826 return -ENOMEM;
1827
1828 if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
1829 err = -EFAULT;
1830 goto done;
1831 }
1832
1833 hdr = (struct mgmt_hdr *) buf;
1834 opcode = get_unaligned_le16(&hdr->opcode);
4e51eae9 1835 index = get_unaligned_le16(&hdr->index);
0381101f
JH
1836 len = get_unaligned_le16(&hdr->len);
1837
1838 if (len != msglen - sizeof(*hdr)) {
1839 err = -EINVAL;
1840 goto done;
1841 }
1842
1843 switch (opcode) {
02d98129
JH
1844 case MGMT_OP_READ_VERSION:
1845 err = read_version(sk);
1846 break;
faba42eb
JH
1847 case MGMT_OP_READ_INDEX_LIST:
1848 err = read_index_list(sk);
1849 break;
f7b64e69 1850 case MGMT_OP_READ_INFO:
4e51eae9 1851 err = read_controller_info(sk, index);
f7b64e69 1852 break;
eec8d2bc 1853 case MGMT_OP_SET_POWERED:
4e51eae9 1854 err = set_powered(sk, index, buf + sizeof(*hdr), len);
eec8d2bc 1855 break;
73f22f62 1856 case MGMT_OP_SET_DISCOVERABLE:
4e51eae9 1857 err = set_discoverable(sk, index, buf + sizeof(*hdr), len);
73f22f62 1858 break;
9fbcbb45 1859 case MGMT_OP_SET_CONNECTABLE:
4e51eae9 1860 err = set_connectable(sk, index, buf + sizeof(*hdr), len);
9fbcbb45 1861 break;
c542a06c 1862 case MGMT_OP_SET_PAIRABLE:
4e51eae9 1863 err = set_pairable(sk, index, buf + sizeof(*hdr), len);
c542a06c 1864 break;
2aeb9a1a 1865 case MGMT_OP_ADD_UUID:
4e51eae9 1866 err = add_uuid(sk, index, buf + sizeof(*hdr), len);
2aeb9a1a
JH
1867 break;
1868 case MGMT_OP_REMOVE_UUID:
4e51eae9 1869 err = remove_uuid(sk, index, buf + sizeof(*hdr), len);
2aeb9a1a 1870 break;
1aff6f09 1871 case MGMT_OP_SET_DEV_CLASS:
4e51eae9 1872 err = set_dev_class(sk, index, buf + sizeof(*hdr), len);
1aff6f09
JH
1873 break;
1874 case MGMT_OP_SET_SERVICE_CACHE:
4e51eae9 1875 err = set_service_cache(sk, index, buf + sizeof(*hdr), len);
1aff6f09 1876 break;
55ed8ca1 1877 case MGMT_OP_LOAD_KEYS:
4e51eae9 1878 err = load_keys(sk, index, buf + sizeof(*hdr), len);
55ed8ca1
JH
1879 break;
1880 case MGMT_OP_REMOVE_KEY:
4e51eae9 1881 err = remove_key(sk, index, buf + sizeof(*hdr), len);
55ed8ca1 1882 break;
8962ee74 1883 case MGMT_OP_DISCONNECT:
4e51eae9 1884 err = disconnect(sk, index, buf + sizeof(*hdr), len);
8962ee74 1885 break;
2784eb41 1886 case MGMT_OP_GET_CONNECTIONS:
8ce6284e 1887 err = get_connections(sk, index);
2784eb41 1888 break;
980e1a53 1889 case MGMT_OP_PIN_CODE_REPLY:
4e51eae9 1890 err = pin_code_reply(sk, index, buf + sizeof(*hdr), len);
980e1a53
JH
1891 break;
1892 case MGMT_OP_PIN_CODE_NEG_REPLY:
4e51eae9 1893 err = pin_code_neg_reply(sk, index, buf + sizeof(*hdr), len);
980e1a53 1894 break;
17fa4b9d 1895 case MGMT_OP_SET_IO_CAPABILITY:
4e51eae9 1896 err = set_io_capability(sk, index, buf + sizeof(*hdr), len);
17fa4b9d 1897 break;
e9a416b5 1898 case MGMT_OP_PAIR_DEVICE:
4e51eae9 1899 err = pair_device(sk, index, buf + sizeof(*hdr), len);
e9a416b5 1900 break;
a5c29683 1901 case MGMT_OP_USER_CONFIRM_REPLY:
4e51eae9 1902 err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 1);
a5c29683
JH
1903 break;
1904 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
4e51eae9 1905 err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 0);
a5c29683 1906 break;
b312b161
JH
1907 case MGMT_OP_SET_LOCAL_NAME:
1908 err = set_local_name(sk, index, buf + sizeof(*hdr), len);
1909 break;
c35938b2
SJ
1910 case MGMT_OP_READ_LOCAL_OOB_DATA:
1911 err = read_local_oob_data(sk, index);
1912 break;
2763eda6
SJ
1913 case MGMT_OP_ADD_REMOTE_OOB_DATA:
1914 err = add_remote_oob_data(sk, index, buf + sizeof(*hdr), len);
1915 break;
1916 case MGMT_OP_REMOVE_REMOTE_OOB_DATA:
1917 err = remove_remote_oob_data(sk, index, buf + sizeof(*hdr),
1918 len);
1919 break;
14a53664
JH
1920 case MGMT_OP_START_DISCOVERY:
1921 err = start_discovery(sk, index);
1922 break;
1923 case MGMT_OP_STOP_DISCOVERY:
1924 err = stop_discovery(sk, index);
1925 break;
7fbec224
AJ
1926 case MGMT_OP_BLOCK_DEVICE:
1927 err = block_device(sk, index, buf + sizeof(*hdr), len);
1928 break;
1929 case MGMT_OP_UNBLOCK_DEVICE:
1930 err = unblock_device(sk, index, buf + sizeof(*hdr), len);
1931 break;
f6422ec6
AJ
1932 case MGMT_OP_SET_FAST_CONNECTABLE:
1933 err = set_fast_connectable(sk, index, buf + sizeof(*hdr),
1934 len);
1935 break;
0381101f
JH
1936 default:
1937 BT_DBG("Unknown op %u", opcode);
4e51eae9 1938 err = cmd_status(sk, index, opcode, 0x01);
0381101f
JH
1939 break;
1940 }
1941
e41d8b4e
JH
1942 if (err < 0)
1943 goto done;
1944
0381101f
JH
1945 err = msglen;
1946
1947done:
1948 kfree(buf);
1949 return err;
1950}
c71e97bf 1951
b24752fe
JH
1952static void cmd_status_rsp(struct pending_cmd *cmd, void *data)
1953{
1954 u8 *status = data;
1955
1956 cmd_status(cmd->sk, cmd->index, cmd->opcode, *status);
1957 mgmt_pending_remove(cmd);
1958}
1959
c71e97bf
JH
1960int mgmt_index_added(u16 index)
1961{
4e51eae9 1962 return mgmt_event(MGMT_EV_INDEX_ADDED, index, NULL, 0, NULL);
c71e97bf
JH
1963}
1964
1965int mgmt_index_removed(u16 index)
1966{
b24752fe
JH
1967 u8 status = ENODEV;
1968
1969 mgmt_pending_foreach(0, index, cmd_status_rsp, &status);
1970
4e51eae9 1971 return mgmt_event(MGMT_EV_INDEX_REMOVED, index, NULL, 0, NULL);
eec8d2bc
JH
1972}
1973
73f22f62 1974struct cmd_lookup {
72a734ec 1975 u8 val;
eec8d2bc
JH
1976 struct sock *sk;
1977};
1978
72a734ec 1979static void mode_rsp(struct pending_cmd *cmd, void *data)
eec8d2bc 1980{
c68fb7ff 1981 struct mgmt_mode *cp = cmd->param;
73f22f62 1982 struct cmd_lookup *match = data;
eec8d2bc 1983
72a734ec 1984 if (cp->val != match->val)
eec8d2bc
JH
1985 return;
1986
053f0211 1987 send_mode_rsp(cmd->sk, cmd->opcode, cmd->index, cp->val);
eec8d2bc
JH
1988
1989 list_del(&cmd->list);
1990
1991 if (match->sk == NULL) {
1992 match->sk = cmd->sk;
1993 sock_hold(match->sk);
1994 }
1995
1996 mgmt_pending_free(cmd);
c71e97bf 1997}
5add6af8
JH
1998
1999int mgmt_powered(u16 index, u8 powered)
2000{
72a734ec 2001 struct mgmt_mode ev;
73f22f62 2002 struct cmd_lookup match = { powered, NULL };
eec8d2bc 2003 int ret;
5add6af8 2004
72a734ec 2005 mgmt_pending_foreach(MGMT_OP_SET_POWERED, index, mode_rsp, &match);
5add6af8 2006
b24752fe
JH
2007 if (!powered) {
2008 u8 status = ENETDOWN;
2009 mgmt_pending_foreach(0, index, cmd_status_rsp, &status);
2010 }
2011
72a734ec 2012 ev.val = powered;
eec8d2bc 2013
4e51eae9 2014 ret = mgmt_event(MGMT_EV_POWERED, index, &ev, sizeof(ev), match.sk);
eec8d2bc
JH
2015
2016 if (match.sk)
2017 sock_put(match.sk);
2018
2019 return ret;
5add6af8 2020}
73f22f62 2021
73f22f62
JH
2022int mgmt_discoverable(u16 index, u8 discoverable)
2023{
72a734ec 2024 struct mgmt_mode ev;
73f22f62
JH
2025 struct cmd_lookup match = { discoverable, NULL };
2026 int ret;
2027
b8534e0f 2028 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index, mode_rsp, &match);
72a734ec 2029
72a734ec 2030 ev.val = discoverable;
73f22f62 2031
4e51eae9
SJ
2032 ret = mgmt_event(MGMT_EV_DISCOVERABLE, index, &ev, sizeof(ev),
2033 match.sk);
73f22f62
JH
2034
2035 if (match.sk)
2036 sock_put(match.sk);
2037
2038 return ret;
2039}
9fbcbb45 2040
9fbcbb45
JH
2041int mgmt_connectable(u16 index, u8 connectable)
2042{
72a734ec 2043 struct mgmt_mode ev;
9fbcbb45
JH
2044 struct cmd_lookup match = { connectable, NULL };
2045 int ret;
2046
72a734ec 2047 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index, mode_rsp, &match);
9fbcbb45 2048
72a734ec 2049 ev.val = connectable;
9fbcbb45 2050
4e51eae9 2051 ret = mgmt_event(MGMT_EV_CONNECTABLE, index, &ev, sizeof(ev), match.sk);
9fbcbb45
JH
2052
2053 if (match.sk)
2054 sock_put(match.sk);
2055
2056 return ret;
2057}
55ed8ca1 2058
4df378a1 2059int mgmt_new_key(u16 index, struct link_key *key, u8 persistent)
55ed8ca1 2060{
a492cd52 2061 struct mgmt_ev_new_key ev;
55ed8ca1 2062
a492cd52 2063 memset(&ev, 0, sizeof(ev));
55ed8ca1 2064
a492cd52
VCG
2065 ev.store_hint = persistent;
2066 bacpy(&ev.key.bdaddr, &key->bdaddr);
2067 ev.key.type = key->type;
2068 memcpy(ev.key.val, key->val, 16);
2069 ev.key.pin_len = key->pin_len;
55ed8ca1 2070
a492cd52 2071 return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL);
55ed8ca1 2072}
f7520543 2073
cfafccf7 2074int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type)
f7520543
JH
2075{
2076 struct mgmt_ev_connected ev;
2077
f7520543 2078 bacpy(&ev.bdaddr, bdaddr);
cfafccf7 2079 ev.link_type = link_type;
f7520543 2080
4e51eae9 2081 return mgmt_event(MGMT_EV_CONNECTED, index, &ev, sizeof(ev), NULL);
f7520543
JH
2082}
2083
8962ee74
JH
2084static void disconnect_rsp(struct pending_cmd *cmd, void *data)
2085{
c68fb7ff 2086 struct mgmt_cp_disconnect *cp = cmd->param;
8962ee74 2087 struct sock **sk = data;
a38528f1 2088 struct mgmt_rp_disconnect rp;
8962ee74 2089
a38528f1 2090 bacpy(&rp.bdaddr, &cp->bdaddr);
8962ee74 2091
4e51eae9 2092 cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, &rp, sizeof(rp));
8962ee74
JH
2093
2094 *sk = cmd->sk;
2095 sock_hold(*sk);
2096
a664b5bc 2097 mgmt_pending_remove(cmd);
8962ee74
JH
2098}
2099
f7520543
JH
2100int mgmt_disconnected(u16 index, bdaddr_t *bdaddr)
2101{
2102 struct mgmt_ev_disconnected ev;
8962ee74
JH
2103 struct sock *sk = NULL;
2104 int err;
2105
2106 mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk);
f7520543 2107
f7520543
JH
2108 bacpy(&ev.bdaddr, bdaddr);
2109
4e51eae9 2110 err = mgmt_event(MGMT_EV_DISCONNECTED, index, &ev, sizeof(ev), sk);
8962ee74
JH
2111
2112 if (sk)
2113 sock_put(sk);
2114
2115 return err;
2116}
2117
2118int mgmt_disconnect_failed(u16 index)
2119{
2120 struct pending_cmd *cmd;
2121 int err;
2122
2123 cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, index);
2124 if (!cmd)
2125 return -ENOENT;
2126
4e51eae9 2127 err = cmd_status(cmd->sk, index, MGMT_OP_DISCONNECT, EIO);
8962ee74 2128
a664b5bc 2129 mgmt_pending_remove(cmd);
8962ee74
JH
2130
2131 return err;
f7520543 2132}
17d5c04c
JH
2133
2134int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status)
2135{
2136 struct mgmt_ev_connect_failed ev;
2137
17d5c04c
JH
2138 bacpy(&ev.bdaddr, bdaddr);
2139 ev.status = status;
2140
4e51eae9 2141 return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL);
17d5c04c 2142}
980e1a53 2143
a770bb5a 2144int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure)
980e1a53
JH
2145{
2146 struct mgmt_ev_pin_code_request ev;
2147
980e1a53 2148 bacpy(&ev.bdaddr, bdaddr);
a770bb5a 2149 ev.secure = secure;
980e1a53 2150
4e51eae9
SJ
2151 return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev),
2152 NULL);
980e1a53
JH
2153}
2154
2155int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
2156{
2157 struct pending_cmd *cmd;
ac56fb13 2158 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
2159 int err;
2160
2161 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, index);
2162 if (!cmd)
2163 return -ENOENT;
2164
ac56fb13
JH
2165 bacpy(&rp.bdaddr, bdaddr);
2166 rp.status = status;
2167
4e51eae9
SJ
2168 err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_REPLY, &rp,
2169 sizeof(rp));
980e1a53 2170
a664b5bc 2171 mgmt_pending_remove(cmd);
980e1a53
JH
2172
2173 return err;
2174}
2175
2176int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
2177{
2178 struct pending_cmd *cmd;
ac56fb13 2179 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
2180 int err;
2181
2182 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, index);
2183 if (!cmd)
2184 return -ENOENT;
2185
ac56fb13
JH
2186 bacpy(&rp.bdaddr, bdaddr);
2187 rp.status = status;
2188
4e51eae9
SJ
2189 err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, &rp,
2190 sizeof(rp));
980e1a53 2191
a664b5bc 2192 mgmt_pending_remove(cmd);
980e1a53
JH
2193
2194 return err;
2195}
a5c29683 2196
55bc1a37
JH
2197int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value,
2198 u8 confirm_hint)
a5c29683
JH
2199{
2200 struct mgmt_ev_user_confirm_request ev;
2201
2202 BT_DBG("hci%u", index);
2203
a5c29683 2204 bacpy(&ev.bdaddr, bdaddr);
55bc1a37 2205 ev.confirm_hint = confirm_hint;
a5c29683
JH
2206 put_unaligned_le32(value, &ev.value);
2207
4e51eae9
SJ
2208 return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev),
2209 NULL);
a5c29683
JH
2210}
2211
2212static int confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status,
2213 u8 opcode)
2214{
2215 struct pending_cmd *cmd;
2216 struct mgmt_rp_user_confirm_reply rp;
2217 int err;
2218
2219 cmd = mgmt_pending_find(opcode, index);
2220 if (!cmd)
2221 return -ENOENT;
2222
a5c29683
JH
2223 bacpy(&rp.bdaddr, bdaddr);
2224 rp.status = status;
4e51eae9 2225 err = cmd_complete(cmd->sk, index, opcode, &rp, sizeof(rp));
a5c29683 2226
a664b5bc 2227 mgmt_pending_remove(cmd);
a5c29683
JH
2228
2229 return err;
2230}
2231
2232int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
2233{
2234 return confirm_reply_complete(index, bdaddr, status,
2235 MGMT_OP_USER_CONFIRM_REPLY);
2236}
2237
b8534e0f 2238int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
a5c29683
JH
2239{
2240 return confirm_reply_complete(index, bdaddr, status,
2241 MGMT_OP_USER_CONFIRM_NEG_REPLY);
2242}
2a611692
JH
2243
2244int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status)
2245{
2246 struct mgmt_ev_auth_failed ev;
2247
2a611692
JH
2248 bacpy(&ev.bdaddr, bdaddr);
2249 ev.status = status;
2250
4e51eae9 2251 return mgmt_event(MGMT_EV_AUTH_FAILED, index, &ev, sizeof(ev), NULL);
2a611692 2252}
b312b161
JH
2253
2254int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status)
2255{
2256 struct pending_cmd *cmd;
80a1e1db 2257 struct hci_dev *hdev;
b312b161
JH
2258 struct mgmt_cp_set_local_name ev;
2259 int err;
2260
2261 memset(&ev, 0, sizeof(ev));
2262 memcpy(ev.name, name, HCI_MAX_NAME_LENGTH);
2263
2264 cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, index);
2265 if (!cmd)
2266 goto send_event;
2267
2268 if (status) {
2269 err = cmd_status(cmd->sk, index, MGMT_OP_SET_LOCAL_NAME, EIO);
2270 goto failed;
2271 }
2272
80a1e1db
JH
2273 hdev = hci_dev_get(index);
2274 if (hdev) {
2275 hci_dev_lock_bh(hdev);
2276 update_eir(hdev);
2277 hci_dev_unlock_bh(hdev);
2278 hci_dev_put(hdev);
2279 }
2280
b312b161
JH
2281 err = cmd_complete(cmd->sk, index, MGMT_OP_SET_LOCAL_NAME, &ev,
2282 sizeof(ev));
2283 if (err < 0)
2284 goto failed;
2285
2286send_event:
2287 err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, index, &ev, sizeof(ev),
2288 cmd ? cmd->sk : NULL);
2289
2290failed:
2291 if (cmd)
2292 mgmt_pending_remove(cmd);
2293 return err;
2294}
c35938b2
SJ
2295
2296int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
2297 u8 status)
2298{
2299 struct pending_cmd *cmd;
2300 int err;
2301
2302 BT_DBG("hci%u status %u", index, status);
2303
2304 cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index);
2305 if (!cmd)
2306 return -ENOENT;
2307
2308 if (status) {
2309 err = cmd_status(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
2310 EIO);
2311 } else {
2312 struct mgmt_rp_read_local_oob_data rp;
2313
2314 memcpy(rp.hash, hash, sizeof(rp.hash));
2315 memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer));
2316
2317 err = cmd_complete(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
2318 &rp, sizeof(rp));
2319 }
2320
2321 mgmt_pending_remove(cmd);
2322
2323 return err;
2324}
e17acd40
JH
2325
2326int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi,
2327 u8 *eir)
2328{
2329 struct mgmt_ev_device_found ev;
2330
2331 memset(&ev, 0, sizeof(ev));
2332
2333 bacpy(&ev.bdaddr, bdaddr);
e17acd40
JH
2334 ev.rssi = rssi;
2335
2336 if (eir)
2337 memcpy(ev.eir, eir, sizeof(ev.eir));
2338
f8523598
AG
2339 if (dev_class)
2340 memcpy(ev.dev_class, dev_class, sizeof(ev.dev_class));
2341
e17acd40
JH
2342 return mgmt_event(MGMT_EV_DEVICE_FOUND, index, &ev, sizeof(ev), NULL);
2343}
a88a9652
JH
2344
2345int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name)
2346{
2347 struct mgmt_ev_remote_name ev;
2348
2349 memset(&ev, 0, sizeof(ev));
2350
2351 bacpy(&ev.bdaddr, bdaddr);
2352 memcpy(ev.name, name, HCI_MAX_NAME_LENGTH);
2353
2354 return mgmt_event(MGMT_EV_REMOTE_NAME, index, &ev, sizeof(ev), NULL);
2355}
314b2381 2356
164a6e78
JH
2357int mgmt_inquiry_failed(u16 index, u8 status)
2358{
2359 struct pending_cmd *cmd;
2360 int err;
2361
2362 cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, index);
2363 if (!cmd)
2364 return -ENOENT;
2365
2366 err = cmd_status(cmd->sk, index, cmd->opcode, status);
2367 mgmt_pending_remove(cmd);
2368
2369 return err;
2370}
2371
314b2381
JH
2372int mgmt_discovering(u16 index, u8 discovering)
2373{
164a6e78
JH
2374 struct pending_cmd *cmd;
2375
2376 if (discovering)
2377 cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, index);
2378 else
2379 cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, index);
2380
2381 if (cmd != NULL) {
2382 cmd_complete(cmd->sk, index, cmd->opcode, NULL, 0);
2383 mgmt_pending_remove(cmd);
2384 }
2385
314b2381
JH
2386 return mgmt_event(MGMT_EV_DISCOVERING, index, &discovering,
2387 sizeof(discovering), NULL);
2388}
5e762444
AJ
2389
2390int mgmt_device_blocked(u16 index, bdaddr_t *bdaddr)
2391{
2392 struct pending_cmd *cmd;
2393 struct mgmt_ev_device_blocked ev;
2394
2395 cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, index);
2396
2397 bacpy(&ev.bdaddr, bdaddr);
2398
2399 return mgmt_event(MGMT_EV_DEVICE_BLOCKED, index, &ev, sizeof(ev),
2400 cmd ? cmd->sk : NULL);
2401}
2402
2403int mgmt_device_unblocked(u16 index, bdaddr_t *bdaddr)
2404{
2405 struct pending_cmd *cmd;
2406 struct mgmt_ev_device_unblocked ev;
2407
2408 cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, index);
2409
2410 bacpy(&ev.bdaddr, bdaddr);
2411
2412 return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, index, &ev, sizeof(ev),
2413 cmd ? cmd->sk : NULL);
2414}