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