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