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