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