Bluetooth: Move mgmt_set_fast_connectable to the right location
[GitHub/mt8127/android_kernel_alcatel_ttab.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
ca69b795 25#include <linux/kernel.h>
72359753 26#include <linux/uaccess.h>
0381101f
JH
27#include <asm/unaligned.h>
28
29#include <net/bluetooth/bluetooth.h>
30#include <net/bluetooth/hci_core.h>
31#include <net/bluetooth/mgmt.h>
32
02d98129
JH
33#define MGMT_VERSION 0
34#define MGMT_REVISION 1
35
2519a1fc
AG
36#define INQUIRY_LEN_BREDR 0x08 /* TGAP(100) */
37
eec8d2bc
JH
38struct pending_cmd {
39 struct list_head list;
fc2f4b13 40 u16 opcode;
eec8d2bc 41 int index;
c68fb7ff 42 void *param;
eec8d2bc 43 struct sock *sk;
e9a416b5 44 void *user_data;
eec8d2bc
JH
45};
46
ca69b795
JH
47/* HCI to MGMT error code conversion table */
48static u8 mgmt_status_table[] = {
49 MGMT_STATUS_SUCCESS,
50 MGMT_STATUS_UNKNOWN_COMMAND, /* Unknown Command */
51 MGMT_STATUS_NOT_CONNECTED, /* No Connection */
52 MGMT_STATUS_FAILED, /* Hardware Failure */
53 MGMT_STATUS_CONNECT_FAILED, /* Page Timeout */
54 MGMT_STATUS_AUTH_FAILED, /* Authentication Failed */
55 MGMT_STATUS_NOT_PAIRED, /* PIN or Key Missing */
56 MGMT_STATUS_NO_RESOURCES, /* Memory Full */
57 MGMT_STATUS_TIMEOUT, /* Connection Timeout */
58 MGMT_STATUS_NO_RESOURCES, /* Max Number of Connections */
59 MGMT_STATUS_NO_RESOURCES, /* Max Number of SCO Connections */
60 MGMT_STATUS_ALREADY_CONNECTED, /* ACL Connection Exists */
61 MGMT_STATUS_BUSY, /* Command Disallowed */
62 MGMT_STATUS_NO_RESOURCES, /* Rejected Limited Resources */
63 MGMT_STATUS_REJECTED, /* Rejected Security */
64 MGMT_STATUS_REJECTED, /* Rejected Personal */
65 MGMT_STATUS_TIMEOUT, /* Host Timeout */
66 MGMT_STATUS_NOT_SUPPORTED, /* Unsupported Feature */
67 MGMT_STATUS_INVALID_PARAMS, /* Invalid Parameters */
68 MGMT_STATUS_DISCONNECTED, /* OE User Ended Connection */
69 MGMT_STATUS_NO_RESOURCES, /* OE Low Resources */
70 MGMT_STATUS_DISCONNECTED, /* OE Power Off */
71 MGMT_STATUS_DISCONNECTED, /* Connection Terminated */
72 MGMT_STATUS_BUSY, /* Repeated Attempts */
73 MGMT_STATUS_REJECTED, /* Pairing Not Allowed */
74 MGMT_STATUS_FAILED, /* Unknown LMP PDU */
75 MGMT_STATUS_NOT_SUPPORTED, /* Unsupported Remote Feature */
76 MGMT_STATUS_REJECTED, /* SCO Offset Rejected */
77 MGMT_STATUS_REJECTED, /* SCO Interval Rejected */
78 MGMT_STATUS_REJECTED, /* Air Mode Rejected */
79 MGMT_STATUS_INVALID_PARAMS, /* Invalid LMP Parameters */
80 MGMT_STATUS_FAILED, /* Unspecified Error */
81 MGMT_STATUS_NOT_SUPPORTED, /* Unsupported LMP Parameter Value */
82 MGMT_STATUS_FAILED, /* Role Change Not Allowed */
83 MGMT_STATUS_TIMEOUT, /* LMP Response Timeout */
84 MGMT_STATUS_FAILED, /* LMP Error Transaction Collision */
85 MGMT_STATUS_FAILED, /* LMP PDU Not Allowed */
86 MGMT_STATUS_REJECTED, /* Encryption Mode Not Accepted */
87 MGMT_STATUS_FAILED, /* Unit Link Key Used */
88 MGMT_STATUS_NOT_SUPPORTED, /* QoS Not Supported */
89 MGMT_STATUS_TIMEOUT, /* Instant Passed */
90 MGMT_STATUS_NOT_SUPPORTED, /* Pairing Not Supported */
91 MGMT_STATUS_FAILED, /* Transaction Collision */
92 MGMT_STATUS_INVALID_PARAMS, /* Unacceptable Parameter */
93 MGMT_STATUS_REJECTED, /* QoS Rejected */
94 MGMT_STATUS_NOT_SUPPORTED, /* Classification Not Supported */
95 MGMT_STATUS_REJECTED, /* Insufficient Security */
96 MGMT_STATUS_INVALID_PARAMS, /* Parameter Out Of Range */
97 MGMT_STATUS_BUSY, /* Role Switch Pending */
98 MGMT_STATUS_FAILED, /* Slot Violation */
99 MGMT_STATUS_FAILED, /* Role Switch Failed */
100 MGMT_STATUS_INVALID_PARAMS, /* EIR Too Large */
101 MGMT_STATUS_NOT_SUPPORTED, /* Simple Pairing Not Supported */
102 MGMT_STATUS_BUSY, /* Host Busy Pairing */
103 MGMT_STATUS_REJECTED, /* Rejected, No Suitable Channel */
104 MGMT_STATUS_BUSY, /* Controller Busy */
105 MGMT_STATUS_INVALID_PARAMS, /* Unsuitable Connection Interval */
106 MGMT_STATUS_TIMEOUT, /* Directed Advertising Timeout */
107 MGMT_STATUS_AUTH_FAILED, /* Terminated Due to MIC Failure */
108 MGMT_STATUS_CONNECT_FAILED, /* Connection Establishment Failed */
109 MGMT_STATUS_CONNECT_FAILED, /* MAC Connection Failed */
110};
111
112static u8 mgmt_status(u8 hci_status)
113{
114 if (hci_status < ARRAY_SIZE(mgmt_status_table))
115 return mgmt_status_table[hci_status];
116
117 return MGMT_STATUS_FAILED;
118}
119
4e51eae9 120static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
f7b64e69
JH
121{
122 struct sk_buff *skb;
123 struct mgmt_hdr *hdr;
124 struct mgmt_ev_cmd_status *ev;
56b7d137 125 int err;
f7b64e69 126
34eb525c 127 BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status);
f7b64e69
JH
128
129 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC);
130 if (!skb)
131 return -ENOMEM;
132
133 hdr = (void *) skb_put(skb, sizeof(*hdr));
134
135 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS);
4e51eae9 136 hdr->index = cpu_to_le16(index);
f7b64e69
JH
137 hdr->len = cpu_to_le16(sizeof(*ev));
138
139 ev = (void *) skb_put(skb, sizeof(*ev));
140 ev->status = status;
141 put_unaligned_le16(cmd, &ev->opcode);
142
56b7d137
GP
143 err = sock_queue_rcv_skb(sk, skb);
144 if (err < 0)
f7b64e69
JH
145 kfree_skb(skb);
146
56b7d137 147 return err;
f7b64e69
JH
148}
149
4e51eae9
SJ
150static int cmd_complete(struct sock *sk, u16 index, u16 cmd, void *rp,
151 size_t rp_len)
02d98129
JH
152{
153 struct sk_buff *skb;
154 struct mgmt_hdr *hdr;
155 struct mgmt_ev_cmd_complete *ev;
56b7d137 156 int err;
02d98129
JH
157
158 BT_DBG("sock %p", sk);
159
a38528f1 160 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_ATOMIC);
02d98129
JH
161 if (!skb)
162 return -ENOMEM;
163
164 hdr = (void *) skb_put(skb, sizeof(*hdr));
02d98129 165
a38528f1 166 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
4e51eae9 167 hdr->index = cpu_to_le16(index);
a38528f1 168 hdr->len = cpu_to_le16(sizeof(*ev) + rp_len);
02d98129 169
a38528f1
JH
170 ev = (void *) skb_put(skb, sizeof(*ev) + rp_len);
171 put_unaligned_le16(cmd, &ev->opcode);
8020c16a
SJ
172
173 if (rp)
174 memcpy(ev->data, rp, rp_len);
02d98129 175
56b7d137
GP
176 err = sock_queue_rcv_skb(sk, skb);
177 if (err < 0)
02d98129
JH
178 kfree_skb(skb);
179
56b7d137 180 return err;;
02d98129
JH
181}
182
a38528f1
JH
183static int read_version(struct sock *sk)
184{
185 struct mgmt_rp_read_version rp;
186
187 BT_DBG("sock %p", sk);
188
189 rp.version = MGMT_VERSION;
190 put_unaligned_le16(MGMT_REVISION, &rp.revision);
191
4e51eae9
SJ
192 return cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_VERSION, &rp,
193 sizeof(rp));
a38528f1
JH
194}
195
faba42eb
JH
196static int read_index_list(struct sock *sk)
197{
faba42eb
JH
198 struct mgmt_rp_read_index_list *rp;
199 struct list_head *p;
8035ded4 200 struct hci_dev *d;
a38528f1 201 size_t rp_len;
faba42eb 202 u16 count;
a38528f1 203 int i, err;
faba42eb
JH
204
205 BT_DBG("sock %p", sk);
206
207 read_lock(&hci_dev_list_lock);
208
209 count = 0;
210 list_for_each(p, &hci_dev_list) {
211 count++;
212 }
213
a38528f1
JH
214 rp_len = sizeof(*rp) + (2 * count);
215 rp = kmalloc(rp_len, GFP_ATOMIC);
216 if (!rp) {
b2c60d42 217 read_unlock(&hci_dev_list_lock);
faba42eb 218 return -ENOMEM;
b2c60d42 219 }
faba42eb 220
faba42eb
JH
221 put_unaligned_le16(count, &rp->num_controllers);
222
223 i = 0;
8035ded4 224 list_for_each_entry(d, &hci_dev_list, list) {
3243553f 225 if (test_and_clear_bit(HCI_AUTO_OFF, &d->flags))
e0f9309f 226 cancel_delayed_work(&d->power_off);
ab81cbf9
JH
227
228 if (test_bit(HCI_SETUP, &d->flags))
229 continue;
230
faba42eb
JH
231 put_unaligned_le16(d->id, &rp->index[i++]);
232 BT_DBG("Added hci%u", d->id);
233 }
234
235 read_unlock(&hci_dev_list_lock);
236
4e51eae9
SJ
237 err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, rp,
238 rp_len);
faba42eb 239
a38528f1
JH
240 kfree(rp);
241
242 return err;
faba42eb
JH
243}
244
69ab39ea
JH
245static u32 get_supported_settings(struct hci_dev *hdev)
246{
247 u32 settings = 0;
248
249 settings |= MGMT_SETTING_POWERED;
250 settings |= MGMT_SETTING_CONNECTABLE;
251 settings |= MGMT_SETTING_FAST_CONNECTABLE;
252 settings |= MGMT_SETTING_DISCOVERABLE;
253 settings |= MGMT_SETTING_PAIRABLE;
254
255 if (hdev->features[6] & LMP_SIMPLE_PAIR)
256 settings |= MGMT_SETTING_SSP;
257
258 if (!(hdev->features[4] & LMP_NO_BREDR)) {
259 settings |= MGMT_SETTING_BREDR;
260 settings |= MGMT_SETTING_LINK_SECURITY;
261 }
262
263 if (hdev->features[4] & LMP_LE)
264 settings |= MGMT_SETTING_LE;
265
266 return settings;
267}
268
269static u32 get_current_settings(struct hci_dev *hdev)
270{
271 u32 settings = 0;
272
273 if (test_bit(HCI_UP, &hdev->flags))
274 settings |= MGMT_SETTING_POWERED;
275 else
276 return settings;
277
278 if (test_bit(HCI_PSCAN, &hdev->flags))
279 settings |= MGMT_SETTING_CONNECTABLE;
280
281 if (test_bit(HCI_ISCAN, &hdev->flags))
282 settings |= MGMT_SETTING_DISCOVERABLE;
283
284 if (test_bit(HCI_PAIRABLE, &hdev->flags))
285 settings |= MGMT_SETTING_PAIRABLE;
286
287 if (!(hdev->features[4] & LMP_NO_BREDR))
288 settings |= MGMT_SETTING_BREDR;
289
290 if (hdev->extfeatures[0] & LMP_HOST_LE)
291 settings |= MGMT_SETTING_LE;
292
293 if (test_bit(HCI_AUTH, &hdev->flags))
294 settings |= MGMT_SETTING_LINK_SECURITY;
295
296 if (hdev->ssp_mode > 0)
297 settings |= MGMT_SETTING_SSP;
298
299 return settings;
300}
301
4e51eae9 302static int read_controller_info(struct sock *sk, u16 index)
0381101f 303{
a38528f1 304 struct mgmt_rp_read_info rp;
f7b64e69 305 struct hci_dev *hdev;
0381101f 306
4e51eae9 307 BT_DBG("sock %p hci%u", sk, index);
f7b64e69 308
4e51eae9 309 hdev = hci_dev_get(index);
a38528f1 310 if (!hdev)
ca69b795
JH
311 return cmd_status(sk, index, MGMT_OP_READ_INFO,
312 MGMT_STATUS_INVALID_PARAMS);
f7b64e69 313
3243553f
JH
314 if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags))
315 cancel_delayed_work_sync(&hdev->power_off);
ab81cbf9 316
09fd0de5 317 hci_dev_lock(hdev);
f7b64e69 318
ebc99feb
JH
319 set_bit(HCI_MGMT, &hdev->flags);
320
dc4fe30b
JH
321 memset(&rp, 0, sizeof(rp));
322
69ab39ea 323 bacpy(&rp.bdaddr, &hdev->bdaddr);
f7b64e69 324
69ab39ea 325 rp.version = hdev->hci_ver;
f7b64e69 326
69ab39ea
JH
327 put_unaligned_le16(hdev->manufacturer, &rp.manufacturer);
328
329 rp.supported_settings = cpu_to_le32(get_supported_settings(hdev));
330 rp.current_settings = cpu_to_le32(get_current_settings(hdev));
f7b64e69 331
a38528f1 332 memcpy(rp.dev_class, hdev->dev_class, 3);
f7b64e69 333
dc4fe30b
JH
334 memcpy(rp.name, hdev->dev_name, sizeof(hdev->dev_name));
335
09fd0de5 336 hci_dev_unlock(hdev);
f7b64e69 337 hci_dev_put(hdev);
0381101f 338
4e51eae9 339 return cmd_complete(sk, index, MGMT_OP_READ_INFO, &rp, sizeof(rp));
0381101f
JH
340}
341
eec8d2bc
JH
342static void mgmt_pending_free(struct pending_cmd *cmd)
343{
344 sock_put(cmd->sk);
c68fb7ff 345 kfree(cmd->param);
eec8d2bc
JH
346 kfree(cmd);
347}
348
366a0336 349static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
2e58ef3e
JH
350 struct hci_dev *hdev,
351 void *data, u16 len)
eec8d2bc
JH
352{
353 struct pending_cmd *cmd;
354
355 cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
356 if (!cmd)
366a0336 357 return NULL;
eec8d2bc
JH
358
359 cmd->opcode = opcode;
2e58ef3e 360 cmd->index = hdev->id;
eec8d2bc 361
c68fb7ff
SJ
362 cmd->param = kmalloc(len, GFP_ATOMIC);
363 if (!cmd->param) {
eec8d2bc 364 kfree(cmd);
366a0336 365 return NULL;
eec8d2bc
JH
366 }
367
8fce6357
SJ
368 if (data)
369 memcpy(cmd->param, data, len);
eec8d2bc
JH
370
371 cmd->sk = sk;
372 sock_hold(sk);
373
2e58ef3e 374 list_add(&cmd->list, &hdev->mgmt_pending);
eec8d2bc 375
366a0336 376 return cmd;
eec8d2bc
JH
377}
378
744cf19e 379static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev,
eec8d2bc
JH
380 void (*cb)(struct pending_cmd *cmd, void *data),
381 void *data)
382{
383 struct list_head *p, *n;
384
2e58ef3e 385 list_for_each_safe(p, n, &hdev->mgmt_pending) {
eec8d2bc
JH
386 struct pending_cmd *cmd;
387
388 cmd = list_entry(p, struct pending_cmd, list);
389
b24752fe 390 if (opcode > 0 && cmd->opcode != opcode)
eec8d2bc
JH
391 continue;
392
eec8d2bc
JH
393 cb(cmd, data);
394 }
395}
396
2e58ef3e 397static struct pending_cmd *mgmt_pending_find(u16 opcode, struct hci_dev *hdev)
eec8d2bc 398{
8035ded4 399 struct pending_cmd *cmd;
eec8d2bc 400
2e58ef3e 401 list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
2aeabcbe
JH
402 if (cmd->opcode == opcode)
403 return cmd;
eec8d2bc
JH
404 }
405
406 return NULL;
407}
408
a664b5bc 409static void mgmt_pending_remove(struct pending_cmd *cmd)
73f22f62 410{
73f22f62
JH
411 list_del(&cmd->list);
412 mgmt_pending_free(cmd);
413}
414
69ab39ea 415static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev)
8680570b 416{
69ab39ea 417 __le32 settings = cpu_to_le32(get_current_settings(hdev));
8680570b 418
69ab39ea 419 return cmd_complete(sk, hdev->id, opcode, &settings, sizeof(settings));
8680570b
JH
420}
421
4e51eae9 422static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len)
eec8d2bc 423{
72a734ec 424 struct mgmt_mode *cp;
eec8d2bc 425 struct hci_dev *hdev;
366a0336 426 struct pending_cmd *cmd;
366a0336 427 int err, up;
eec8d2bc
JH
428
429 cp = (void *) data;
eec8d2bc 430
4e51eae9 431 BT_DBG("request for hci%u", index);
eec8d2bc 432
bdce7baf 433 if (len != sizeof(*cp))
ca69b795
JH
434 return cmd_status(sk, index, MGMT_OP_SET_POWERED,
435 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 436
4e51eae9 437 hdev = hci_dev_get(index);
eec8d2bc 438 if (!hdev)
ca69b795
JH
439 return cmd_status(sk, index, MGMT_OP_SET_POWERED,
440 MGMT_STATUS_INVALID_PARAMS);
eec8d2bc 441
09fd0de5 442 hci_dev_lock(hdev);
eec8d2bc
JH
443
444 up = test_bit(HCI_UP, &hdev->flags);
72a734ec 445 if ((cp->val && up) || (!cp->val && !up)) {
69ab39ea 446 err = send_settings_rsp(sk, MGMT_OP_SET_POWERED, hdev);
eec8d2bc
JH
447 goto failed;
448 }
449
2e58ef3e 450 if (mgmt_pending_find(MGMT_OP_SET_POWERED, hdev)) {
ca69b795
JH
451 err = cmd_status(sk, index, MGMT_OP_SET_POWERED,
452 MGMT_STATUS_BUSY);
eec8d2bc
JH
453 goto failed;
454 }
455
2e58ef3e 456 cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, hdev, data, len);
366a0336
JH
457 if (!cmd) {
458 err = -ENOMEM;
eec8d2bc 459 goto failed;
366a0336 460 }
eec8d2bc 461
72a734ec 462 if (cp->val)
7f971041 463 schedule_work(&hdev->power_on);
eec8d2bc 464 else
80b7ab33 465 schedule_work(&hdev->power_off.work);
eec8d2bc 466
366a0336 467 err = 0;
eec8d2bc
JH
468
469failed:
09fd0de5 470 hci_dev_unlock(hdev);
eec8d2bc 471 hci_dev_put(hdev);
366a0336 472 return err;
eec8d2bc
JH
473}
474
4e51eae9
SJ
475static int set_discoverable(struct sock *sk, u16 index, unsigned char *data,
476 u16 len)
73f22f62 477{
16ab91ab 478 struct mgmt_cp_set_discoverable *cp;
73f22f62 479 struct hci_dev *hdev;
366a0336 480 struct pending_cmd *cmd;
73f22f62
JH
481 u8 scan;
482 int err;
483
484 cp = (void *) data;
73f22f62 485
4e51eae9 486 BT_DBG("request for hci%u", index);
73f22f62 487
bdce7baf 488 if (len != sizeof(*cp))
ca69b795
JH
489 return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE,
490 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 491
4e51eae9 492 hdev = hci_dev_get(index);
73f22f62 493 if (!hdev)
ca69b795
JH
494 return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE,
495 MGMT_STATUS_INVALID_PARAMS);
73f22f62 496
09fd0de5 497 hci_dev_lock(hdev);
73f22f62
JH
498
499 if (!test_bit(HCI_UP, &hdev->flags)) {
ca69b795
JH
500 err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE,
501 MGMT_STATUS_NOT_POWERED);
73f22f62
JH
502 goto failed;
503 }
504
2e58ef3e
JH
505 if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) ||
506 mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) {
ca69b795
JH
507 err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE,
508 MGMT_STATUS_BUSY);
73f22f62
JH
509 goto failed;
510 }
511
72a734ec 512 if (cp->val == test_bit(HCI_ISCAN, &hdev->flags) &&
73f22f62 513 test_bit(HCI_PSCAN, &hdev->flags)) {
69ab39ea 514 err = send_settings_rsp(sk, MGMT_OP_SET_DISCOVERABLE, hdev);
73f22f62
JH
515 goto failed;
516 }
517
2e58ef3e 518 cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, hdev, data, len);
366a0336
JH
519 if (!cmd) {
520 err = -ENOMEM;
73f22f62 521 goto failed;
366a0336 522 }
73f22f62
JH
523
524 scan = SCAN_PAGE;
525
72a734ec 526 if (cp->val)
73f22f62 527 scan |= SCAN_INQUIRY;
16ab91ab 528 else
e0f9309f 529 cancel_delayed_work(&hdev->discov_off);
73f22f62
JH
530
531 err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
532 if (err < 0)
a664b5bc 533 mgmt_pending_remove(cmd);
73f22f62 534
16ab91ab
JH
535 if (cp->val)
536 hdev->discov_timeout = get_unaligned_le16(&cp->timeout);
537
73f22f62 538failed:
09fd0de5 539 hci_dev_unlock(hdev);
73f22f62
JH
540 hci_dev_put(hdev);
541
542 return err;
543}
544
4e51eae9
SJ
545static int set_connectable(struct sock *sk, u16 index, unsigned char *data,
546 u16 len)
9fbcbb45 547{
72a734ec 548 struct mgmt_mode *cp;
9fbcbb45 549 struct hci_dev *hdev;
366a0336 550 struct pending_cmd *cmd;
9fbcbb45
JH
551 u8 scan;
552 int err;
553
554 cp = (void *) data;
9fbcbb45 555
4e51eae9 556 BT_DBG("request for hci%u", index);
9fbcbb45 557
bdce7baf 558 if (len != sizeof(*cp))
ca69b795
JH
559 return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE,
560 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 561
4e51eae9 562 hdev = hci_dev_get(index);
9fbcbb45 563 if (!hdev)
ca69b795
JH
564 return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE,
565 MGMT_STATUS_INVALID_PARAMS);
9fbcbb45 566
09fd0de5 567 hci_dev_lock(hdev);
9fbcbb45
JH
568
569 if (!test_bit(HCI_UP, &hdev->flags)) {
ca69b795
JH
570 err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE,
571 MGMT_STATUS_NOT_POWERED);
9fbcbb45
JH
572 goto failed;
573 }
574
2e58ef3e
JH
575 if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) ||
576 mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) {
ca69b795
JH
577 err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE,
578 MGMT_STATUS_BUSY);
9fbcbb45
JH
579 goto failed;
580 }
581
72a734ec 582 if (cp->val == test_bit(HCI_PSCAN, &hdev->flags)) {
69ab39ea 583 err = send_settings_rsp(sk, MGMT_OP_SET_CONNECTABLE, hdev);
9fbcbb45
JH
584 goto failed;
585 }
586
2e58ef3e 587 cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, hdev, data, len);
366a0336
JH
588 if (!cmd) {
589 err = -ENOMEM;
9fbcbb45 590 goto failed;
366a0336 591 }
9fbcbb45 592
72a734ec 593 if (cp->val)
9fbcbb45
JH
594 scan = SCAN_PAGE;
595 else
596 scan = 0;
597
598 err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
599 if (err < 0)
a664b5bc 600 mgmt_pending_remove(cmd);
9fbcbb45
JH
601
602failed:
09fd0de5 603 hci_dev_unlock(hdev);
9fbcbb45
JH
604 hci_dev_put(hdev);
605
606 return err;
607}
608
744cf19e
JH
609static int mgmt_event(u16 event, struct hci_dev *hdev, void *data,
610 u16 data_len, struct sock *skip_sk)
c542a06c
JH
611{
612 struct sk_buff *skb;
613 struct mgmt_hdr *hdr;
614
615 skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC);
616 if (!skb)
617 return -ENOMEM;
618
619 bt_cb(skb)->channel = HCI_CHANNEL_CONTROL;
620
621 hdr = (void *) skb_put(skb, sizeof(*hdr));
622 hdr->opcode = cpu_to_le16(event);
744cf19e
JH
623 if (hdev)
624 hdr->index = cpu_to_le16(hdev->id);
625 else
626 hdr->index = cpu_to_le16(MGMT_INDEX_NONE);
c542a06c
JH
627 hdr->len = cpu_to_le16(data_len);
628
4e51eae9
SJ
629 if (data)
630 memcpy(skb_put(skb, data_len), data, data_len);
c542a06c
JH
631
632 hci_send_to_sock(NULL, skb, skip_sk);
633 kfree_skb(skb);
634
635 return 0;
636}
637
4e51eae9
SJ
638static int set_pairable(struct sock *sk, u16 index, unsigned char *data,
639 u16 len)
c542a06c 640{
69ab39ea 641 struct mgmt_mode *cp;
c542a06c 642 struct hci_dev *hdev;
69ab39ea 643 __le32 ev;
c542a06c
JH
644 int err;
645
646 cp = (void *) data;
c542a06c 647
4e51eae9 648 BT_DBG("request for hci%u", index);
c542a06c 649
bdce7baf 650 if (len != sizeof(*cp))
ca69b795
JH
651 return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE,
652 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 653
4e51eae9 654 hdev = hci_dev_get(index);
c542a06c 655 if (!hdev)
ca69b795
JH
656 return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE,
657 MGMT_STATUS_INVALID_PARAMS);
c542a06c 658
09fd0de5 659 hci_dev_lock(hdev);
c542a06c
JH
660
661 if (cp->val)
662 set_bit(HCI_PAIRABLE, &hdev->flags);
663 else
664 clear_bit(HCI_PAIRABLE, &hdev->flags);
665
69ab39ea 666 err = send_settings_rsp(sk, MGMT_OP_SET_PAIRABLE, hdev);
c542a06c
JH
667 if (err < 0)
668 goto failed;
669
69ab39ea 670 ev = cpu_to_le32(get_current_settings(hdev));
c542a06c 671
69ab39ea 672 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), sk);
c542a06c
JH
673
674failed:
09fd0de5 675 hci_dev_unlock(hdev);
c542a06c
JH
676 hci_dev_put(hdev);
677
678 return err;
679}
680
80a1e1db
JH
681#define EIR_FLAGS 0x01 /* flags */
682#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
683#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
684#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */
685#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
686#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */
687#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
688#define EIR_NAME_SHORT 0x08 /* shortened local name */
689#define EIR_NAME_COMPLETE 0x09 /* complete local name */
690#define EIR_TX_POWER 0x0A /* transmit power level */
691#define EIR_DEVICE_ID 0x10 /* device ID */
692
693#define PNP_INFO_SVCLASS_ID 0x1200
694
695static u8 bluetooth_base_uuid[] = {
696 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
697 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
698};
699
700static u16 get_uuid16(u8 *uuid128)
701{
702 u32 val;
703 int i;
704
705 for (i = 0; i < 12; i++) {
706 if (bluetooth_base_uuid[i] != uuid128[i])
707 return 0;
708 }
709
710 memcpy(&val, &uuid128[12], 4);
711
712 val = le32_to_cpu(val);
713 if (val > 0xffff)
714 return 0;
715
716 return (u16) val;
717}
718
719static void create_eir(struct hci_dev *hdev, u8 *data)
720{
721 u8 *ptr = data;
722 u16 eir_len = 0;
723 u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)];
724 int i, truncated = 0;
8035ded4 725 struct bt_uuid *uuid;
80a1e1db
JH
726 size_t name_len;
727
728 name_len = strlen(hdev->dev_name);
729
730 if (name_len > 0) {
731 /* EIR Data type */
732 if (name_len > 48) {
733 name_len = 48;
734 ptr[1] = EIR_NAME_SHORT;
735 } else
736 ptr[1] = EIR_NAME_COMPLETE;
737
738 /* EIR Data length */
739 ptr[0] = name_len + 1;
740
741 memcpy(ptr + 2, hdev->dev_name, name_len);
742
743 eir_len += (name_len + 2);
744 ptr += (name_len + 2);
745 }
746
747 memset(uuid16_list, 0, sizeof(uuid16_list));
748
749 /* Group all UUID16 types */
8035ded4 750 list_for_each_entry(uuid, &hdev->uuids, list) {
80a1e1db
JH
751 u16 uuid16;
752
753 uuid16 = get_uuid16(uuid->uuid);
754 if (uuid16 == 0)
755 return;
756
757 if (uuid16 < 0x1100)
758 continue;
759
760 if (uuid16 == PNP_INFO_SVCLASS_ID)
761 continue;
762
763 /* Stop if not enough space to put next UUID */
764 if (eir_len + 2 + sizeof(u16) > HCI_MAX_EIR_LENGTH) {
765 truncated = 1;
766 break;
767 }
768
769 /* Check for duplicates */
770 for (i = 0; uuid16_list[i] != 0; i++)
771 if (uuid16_list[i] == uuid16)
772 break;
773
774 if (uuid16_list[i] == 0) {
775 uuid16_list[i] = uuid16;
776 eir_len += sizeof(u16);
777 }
778 }
779
780 if (uuid16_list[0] != 0) {
781 u8 *length = ptr;
782
783 /* EIR Data type */
784 ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL;
785
786 ptr += 2;
787 eir_len += 2;
788
789 for (i = 0; uuid16_list[i] != 0; i++) {
790 *ptr++ = (uuid16_list[i] & 0x00ff);
791 *ptr++ = (uuid16_list[i] & 0xff00) >> 8;
792 }
793
794 /* EIR Data length */
795 *length = (i * sizeof(u16)) + 1;
796 }
797}
798
799static int update_eir(struct hci_dev *hdev)
800{
801 struct hci_cp_write_eir cp;
802
803 if (!(hdev->features[6] & LMP_EXT_INQ))
804 return 0;
805
806 if (hdev->ssp_mode == 0)
807 return 0;
808
809 if (test_bit(HCI_SERVICE_CACHE, &hdev->flags))
810 return 0;
811
812 memset(&cp, 0, sizeof(cp));
813
814 create_eir(hdev, cp.data);
815
816 if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0)
817 return 0;
818
819 memcpy(hdev->eir, cp.data, sizeof(cp.data));
820
821 return hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
822}
823
1aff6f09
JH
824static u8 get_service_classes(struct hci_dev *hdev)
825{
12dc0743 826 struct bt_uuid *uuid;
1aff6f09
JH
827 u8 val = 0;
828
12dc0743 829 list_for_each_entry(uuid, &hdev->uuids, list)
1aff6f09 830 val |= uuid->svc_hint;
1aff6f09
JH
831
832 return val;
833}
834
835static int update_class(struct hci_dev *hdev)
836{
837 u8 cod[3];
838
839 BT_DBG("%s", hdev->name);
840
841 if (test_bit(HCI_SERVICE_CACHE, &hdev->flags))
842 return 0;
843
844 cod[0] = hdev->minor_class;
845 cod[1] = hdev->major_class;
846 cod[2] = get_service_classes(hdev);
847
848 if (memcmp(cod, hdev->dev_class, 3) == 0)
849 return 0;
850
851 return hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
852}
853
4e51eae9 854static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
2aeb9a1a
JH
855{
856 struct mgmt_cp_add_uuid *cp;
857 struct hci_dev *hdev;
858 struct bt_uuid *uuid;
2aeb9a1a
JH
859 int err;
860
861 cp = (void *) data;
2aeb9a1a 862
4e51eae9 863 BT_DBG("request for hci%u", index);
2aeb9a1a 864
bdce7baf 865 if (len != sizeof(*cp))
ca69b795
JH
866 return cmd_status(sk, index, MGMT_OP_ADD_UUID,
867 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 868
4e51eae9 869 hdev = hci_dev_get(index);
2aeb9a1a 870 if (!hdev)
ca69b795
JH
871 return cmd_status(sk, index, MGMT_OP_ADD_UUID,
872 MGMT_STATUS_INVALID_PARAMS);
2aeb9a1a 873
09fd0de5 874 hci_dev_lock(hdev);
2aeb9a1a
JH
875
876 uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC);
877 if (!uuid) {
878 err = -ENOMEM;
879 goto failed;
880 }
881
882 memcpy(uuid->uuid, cp->uuid, 16);
1aff6f09 883 uuid->svc_hint = cp->svc_hint;
2aeb9a1a
JH
884
885 list_add(&uuid->list, &hdev->uuids);
886
1aff6f09
JH
887 err = update_class(hdev);
888 if (err < 0)
889 goto failed;
890
80a1e1db
JH
891 err = update_eir(hdev);
892 if (err < 0)
893 goto failed;
894
4e51eae9 895 err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, NULL, 0);
2aeb9a1a
JH
896
897failed:
09fd0de5 898 hci_dev_unlock(hdev);
2aeb9a1a
JH
899 hci_dev_put(hdev);
900
901 return err;
902}
903
4e51eae9 904static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
2aeb9a1a
JH
905{
906 struct list_head *p, *n;
779cb850 907 struct mgmt_cp_remove_uuid *cp;
2aeb9a1a
JH
908 struct hci_dev *hdev;
909 u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2aeb9a1a
JH
910 int err, found;
911
912 cp = (void *) data;
2aeb9a1a 913
4e51eae9 914 BT_DBG("request for hci%u", index);
2aeb9a1a 915
bdce7baf 916 if (len != sizeof(*cp))
ca69b795
JH
917 return cmd_status(sk, index, MGMT_OP_REMOVE_UUID,
918 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 919
4e51eae9 920 hdev = hci_dev_get(index);
2aeb9a1a 921 if (!hdev)
ca69b795
JH
922 return cmd_status(sk, index, MGMT_OP_REMOVE_UUID,
923 MGMT_STATUS_INVALID_PARAMS);
2aeb9a1a 924
09fd0de5 925 hci_dev_lock(hdev);
2aeb9a1a
JH
926
927 if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) {
928 err = hci_uuids_clear(hdev);
929 goto unlock;
930 }
931
932 found = 0;
933
934 list_for_each_safe(p, n, &hdev->uuids) {
935 struct bt_uuid *match = list_entry(p, struct bt_uuid, list);
936
937 if (memcmp(match->uuid, cp->uuid, 16) != 0)
938 continue;
939
940 list_del(&match->list);
941 found++;
942 }
943
944 if (found == 0) {
ca69b795
JH
945 err = cmd_status(sk, index, MGMT_OP_REMOVE_UUID,
946 MGMT_STATUS_INVALID_PARAMS);
2aeb9a1a
JH
947 goto unlock;
948 }
949
1aff6f09
JH
950 err = update_class(hdev);
951 if (err < 0)
952 goto unlock;
953
80a1e1db
JH
954 err = update_eir(hdev);
955 if (err < 0)
956 goto unlock;
957
4e51eae9 958 err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0);
2aeb9a1a
JH
959
960unlock:
09fd0de5 961 hci_dev_unlock(hdev);
2aeb9a1a
JH
962 hci_dev_put(hdev);
963
964 return err;
965}
966
4e51eae9
SJ
967static int set_dev_class(struct sock *sk, u16 index, unsigned char *data,
968 u16 len)
1aff6f09
JH
969{
970 struct hci_dev *hdev;
971 struct mgmt_cp_set_dev_class *cp;
1aff6f09
JH
972 int err;
973
974 cp = (void *) data;
1aff6f09 975
4e51eae9 976 BT_DBG("request for hci%u", index);
1aff6f09 977
bdce7baf 978 if (len != sizeof(*cp))
ca69b795
JH
979 return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS,
980 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 981
4e51eae9 982 hdev = hci_dev_get(index);
1aff6f09 983 if (!hdev)
ca69b795
JH
984 return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS,
985 MGMT_STATUS_INVALID_PARAMS);
1aff6f09 986
09fd0de5 987 hci_dev_lock(hdev);
1aff6f09
JH
988
989 hdev->major_class = cp->major;
990 hdev->minor_class = cp->minor;
991
992 err = update_class(hdev);
993
994 if (err == 0)
4e51eae9 995 err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, NULL, 0);
1aff6f09 996
09fd0de5 997 hci_dev_unlock(hdev);
1aff6f09
JH
998 hci_dev_put(hdev);
999
1000 return err;
1001}
1002
4e51eae9
SJ
1003static int set_service_cache(struct sock *sk, u16 index, unsigned char *data,
1004 u16 len)
1aff6f09
JH
1005{
1006 struct hci_dev *hdev;
1007 struct mgmt_cp_set_service_cache *cp;
1aff6f09
JH
1008 int err;
1009
1010 cp = (void *) data;
1aff6f09 1011
bdce7baf 1012 if (len != sizeof(*cp))
ca69b795
JH
1013 return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE,
1014 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1015
4e51eae9 1016 hdev = hci_dev_get(index);
1aff6f09 1017 if (!hdev)
ca69b795
JH
1018 return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE,
1019 MGMT_STATUS_INVALID_PARAMS);
1aff6f09 1020
09fd0de5 1021 hci_dev_lock(hdev);
1aff6f09 1022
4e51eae9 1023 BT_DBG("hci%u enable %d", index, cp->enable);
1aff6f09
JH
1024
1025 if (cp->enable) {
1026 set_bit(HCI_SERVICE_CACHE, &hdev->flags);
1027 err = 0;
1028 } else {
1029 clear_bit(HCI_SERVICE_CACHE, &hdev->flags);
1030 err = update_class(hdev);
80a1e1db
JH
1031 if (err == 0)
1032 err = update_eir(hdev);
1aff6f09
JH
1033 }
1034
1035 if (err == 0)
4e51eae9
SJ
1036 err = cmd_complete(sk, index, MGMT_OP_SET_SERVICE_CACHE, NULL,
1037 0);
e5b82e58
GP
1038 else
1039 cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, -err);
1040
1aff6f09 1041
09fd0de5 1042 hci_dev_unlock(hdev);
1aff6f09
JH
1043 hci_dev_put(hdev);
1044
1045 return err;
1046}
1047
86742e1e
JH
1048static int load_link_keys(struct sock *sk, u16 index, unsigned char *data,
1049 u16 len)
55ed8ca1
JH
1050{
1051 struct hci_dev *hdev;
86742e1e 1052 struct mgmt_cp_load_link_keys *cp;
4e51eae9 1053 u16 key_count, expected_len;
a492cd52 1054 int i;
55ed8ca1
JH
1055
1056 cp = (void *) data;
bdce7baf
SJ
1057
1058 if (len < sizeof(*cp))
ca69b795
JH
1059 return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS,
1060 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1061
55ed8ca1
JH
1062 key_count = get_unaligned_le16(&cp->key_count);
1063
86742e1e
JH
1064 expected_len = sizeof(*cp) + key_count *
1065 sizeof(struct mgmt_link_key_info);
a492cd52 1066 if (expected_len != len) {
86742e1e 1067 BT_ERR("load_link_keys: expected %u bytes, got %u bytes",
a492cd52 1068 len, expected_len);
ca69b795
JH
1069 return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS,
1070 MGMT_STATUS_INVALID_PARAMS);
55ed8ca1
JH
1071 }
1072
4e51eae9 1073 hdev = hci_dev_get(index);
55ed8ca1 1074 if (!hdev)
ca69b795
JH
1075 return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS,
1076 MGMT_STATUS_INVALID_PARAMS);
55ed8ca1 1077
4e51eae9 1078 BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys,
55ed8ca1
JH
1079 key_count);
1080
09fd0de5 1081 hci_dev_lock(hdev);
55ed8ca1
JH
1082
1083 hci_link_keys_clear(hdev);
1084
1085 set_bit(HCI_LINK_KEYS, &hdev->flags);
1086
1087 if (cp->debug_keys)
1088 set_bit(HCI_DEBUG_KEYS, &hdev->flags);
1089 else
1090 clear_bit(HCI_DEBUG_KEYS, &hdev->flags);
1091
a492cd52 1092 for (i = 0; i < key_count; i++) {
86742e1e 1093 struct mgmt_link_key_info *key = &cp->keys[i];
55ed8ca1 1094
d25e28ab 1095 hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type,
55ed8ca1
JH
1096 key->pin_len);
1097 }
1098
0e5f875a
JH
1099 cmd_complete(sk, index, MGMT_OP_LOAD_LINK_KEYS, NULL, 0);
1100
09fd0de5 1101 hci_dev_unlock(hdev);
55ed8ca1
JH
1102 hci_dev_put(hdev);
1103
a492cd52 1104 return 0;
55ed8ca1
JH
1105}
1106
86742e1e
JH
1107static int remove_keys(struct sock *sk, u16 index, unsigned char *data,
1108 u16 len)
55ed8ca1
JH
1109{
1110 struct hci_dev *hdev;
86742e1e 1111 struct mgmt_cp_remove_keys *cp;
a8a1d19e
JH
1112 struct mgmt_rp_remove_keys rp;
1113 struct hci_cp_disconnect dc;
1114 struct pending_cmd *cmd;
55ed8ca1 1115 struct hci_conn *conn;
55ed8ca1
JH
1116 int err;
1117
1118 cp = (void *) data;
55ed8ca1 1119
bdce7baf 1120 if (len != sizeof(*cp))
ca69b795
JH
1121 return cmd_status(sk, index, MGMT_OP_REMOVE_KEYS,
1122 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1123
4e51eae9 1124 hdev = hci_dev_get(index);
55ed8ca1 1125 if (!hdev)
ca69b795
JH
1126 return cmd_status(sk, index, MGMT_OP_REMOVE_KEYS,
1127 MGMT_STATUS_INVALID_PARAMS);
55ed8ca1 1128
09fd0de5 1129 hci_dev_lock(hdev);
55ed8ca1 1130
a8a1d19e
JH
1131 memset(&rp, 0, sizeof(rp));
1132 bacpy(&rp.bdaddr, &cp->bdaddr);
ca69b795 1133 rp.status = MGMT_STATUS_FAILED;
a8a1d19e 1134
55ed8ca1 1135 err = hci_remove_link_key(hdev, &cp->bdaddr);
ca69b795
JH
1136 if (err < 0) {
1137 rp.status = MGMT_STATUS_NOT_PAIRED;
55ed8ca1 1138 goto unlock;
ca69b795 1139 }
55ed8ca1 1140
a8a1d19e
JH
1141 if (!test_bit(HCI_UP, &hdev->flags) || !cp->disconnect) {
1142 err = cmd_complete(sk, index, MGMT_OP_REMOVE_KEYS, &rp,
1143 sizeof(rp));
55ed8ca1 1144 goto unlock;
a8a1d19e 1145 }
55ed8ca1
JH
1146
1147 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
a8a1d19e
JH
1148 if (!conn) {
1149 err = cmd_complete(sk, index, MGMT_OP_REMOVE_KEYS, &rp,
1150 sizeof(rp));
1151 goto unlock;
1152 }
55ed8ca1 1153
a8a1d19e
JH
1154 cmd = mgmt_pending_add(sk, MGMT_OP_REMOVE_KEYS, hdev, cp, sizeof(*cp));
1155 if (!cmd) {
1156 err = -ENOMEM;
1157 goto unlock;
55ed8ca1
JH
1158 }
1159
a8a1d19e
JH
1160 put_unaligned_le16(conn->handle, &dc.handle);
1161 dc.reason = 0x13; /* Remote User Terminated Connection */
1162 err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc);
1163 if (err < 0)
1164 mgmt_pending_remove(cmd);
1165
55ed8ca1 1166unlock:
ca69b795 1167 if (err < 0)
a8a1d19e
JH
1168 err = cmd_complete(sk, index, MGMT_OP_REMOVE_KEYS, &rp,
1169 sizeof(rp));
09fd0de5 1170 hci_dev_unlock(hdev);
55ed8ca1
JH
1171 hci_dev_put(hdev);
1172
1173 return err;
1174}
1175
4e51eae9 1176static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len)
8962ee74
JH
1177{
1178 struct hci_dev *hdev;
1179 struct mgmt_cp_disconnect *cp;
1180 struct hci_cp_disconnect dc;
366a0336 1181 struct pending_cmd *cmd;
8962ee74 1182 struct hci_conn *conn;
8962ee74
JH
1183 int err;
1184
1185 BT_DBG("");
1186
1187 cp = (void *) data;
8962ee74 1188
bdce7baf 1189 if (len != sizeof(*cp))
ca69b795
JH
1190 return cmd_status(sk, index, MGMT_OP_DISCONNECT,
1191 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1192
4e51eae9 1193 hdev = hci_dev_get(index);
8962ee74 1194 if (!hdev)
ca69b795
JH
1195 return cmd_status(sk, index, MGMT_OP_DISCONNECT,
1196 MGMT_STATUS_INVALID_PARAMS);
8962ee74 1197
09fd0de5 1198 hci_dev_lock(hdev);
8962ee74
JH
1199
1200 if (!test_bit(HCI_UP, &hdev->flags)) {
ca69b795
JH
1201 err = cmd_status(sk, index, MGMT_OP_DISCONNECT,
1202 MGMT_STATUS_NOT_POWERED);
8962ee74
JH
1203 goto failed;
1204 }
1205
2e58ef3e 1206 if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) {
ca69b795
JH
1207 err = cmd_status(sk, index, MGMT_OP_DISCONNECT,
1208 MGMT_STATUS_BUSY);
8962ee74
JH
1209 goto failed;
1210 }
1211
1212 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
365227e5
VCG
1213 if (!conn)
1214 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->bdaddr);
1215
8962ee74 1216 if (!conn) {
ca69b795
JH
1217 err = cmd_status(sk, index, MGMT_OP_DISCONNECT,
1218 MGMT_STATUS_NOT_CONNECTED);
8962ee74
JH
1219 goto failed;
1220 }
1221
2e58ef3e 1222 cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, hdev, data, len);
366a0336
JH
1223 if (!cmd) {
1224 err = -ENOMEM;
8962ee74 1225 goto failed;
366a0336 1226 }
8962ee74
JH
1227
1228 put_unaligned_le16(conn->handle, &dc.handle);
1229 dc.reason = 0x13; /* Remote User Terminated Connection */
1230
1231 err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc);
1232 if (err < 0)
a664b5bc 1233 mgmt_pending_remove(cmd);
8962ee74
JH
1234
1235failed:
09fd0de5 1236 hci_dev_unlock(hdev);
8962ee74
JH
1237 hci_dev_put(hdev);
1238
1239 return err;
1240}
1241
48264f06 1242static u8 link_to_mgmt(u8 link_type, u8 addr_type)
4c659c39
JH
1243{
1244 switch (link_type) {
1245 case LE_LINK:
48264f06
JH
1246 switch (addr_type) {
1247 case ADDR_LE_DEV_PUBLIC:
1248 return MGMT_ADDR_LE_PUBLIC;
1249 case ADDR_LE_DEV_RANDOM:
1250 return MGMT_ADDR_LE_RANDOM;
1251 default:
1252 return MGMT_ADDR_INVALID;
1253 }
4c659c39
JH
1254 case ACL_LINK:
1255 return MGMT_ADDR_BREDR;
1256 default:
1257 return MGMT_ADDR_INVALID;
1258 }
1259}
1260
8ce6284e 1261static int get_connections(struct sock *sk, u16 index)
2784eb41 1262{
2784eb41
JH
1263 struct mgmt_rp_get_connections *rp;
1264 struct hci_dev *hdev;
8035ded4 1265 struct hci_conn *c;
2784eb41 1266 struct list_head *p;
a38528f1 1267 size_t rp_len;
4e51eae9 1268 u16 count;
2784eb41
JH
1269 int i, err;
1270
1271 BT_DBG("");
1272
4e51eae9 1273 hdev = hci_dev_get(index);
2784eb41 1274 if (!hdev)
ca69b795
JH
1275 return cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS,
1276 MGMT_STATUS_INVALID_PARAMS);
2784eb41 1277
09fd0de5 1278 hci_dev_lock(hdev);
2784eb41
JH
1279
1280 count = 0;
1281 list_for_each(p, &hdev->conn_hash.list) {
1282 count++;
1283 }
1284
4c659c39 1285 rp_len = sizeof(*rp) + (count * sizeof(struct mgmt_addr_info));
a38528f1
JH
1286 rp = kmalloc(rp_len, GFP_ATOMIC);
1287 if (!rp) {
2784eb41
JH
1288 err = -ENOMEM;
1289 goto unlock;
1290 }
1291
2784eb41
JH
1292 put_unaligned_le16(count, &rp->conn_count);
1293
2784eb41 1294 i = 0;
4c659c39
JH
1295 list_for_each_entry(c, &hdev->conn_hash.list, list) {
1296 bacpy(&rp->addr[i].bdaddr, &c->dst);
48264f06 1297 rp->addr[i].type = link_to_mgmt(c->type, c->dst_type);
4c659c39
JH
1298 if (rp->addr[i].type == MGMT_ADDR_INVALID)
1299 continue;
1300 i++;
1301 }
1302
1303 /* Recalculate length in case of filtered SCO connections, etc */
1304 rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info));
2784eb41 1305
4e51eae9 1306 err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len);
2784eb41
JH
1307
1308unlock:
a38528f1 1309 kfree(rp);
09fd0de5 1310 hci_dev_unlock(hdev);
2784eb41
JH
1311 hci_dev_put(hdev);
1312 return err;
1313}
1314
96d97a67
WR
1315static int send_pin_code_neg_reply(struct sock *sk, u16 index,
1316 struct hci_dev *hdev, struct mgmt_cp_pin_code_neg_reply *cp)
1317{
1318 struct pending_cmd *cmd;
1319 int err;
1320
2e58ef3e 1321 cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, hdev, cp,
96d97a67
WR
1322 sizeof(*cp));
1323 if (!cmd)
1324 return -ENOMEM;
1325
1326 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(cp->bdaddr),
1327 &cp->bdaddr);
1328 if (err < 0)
1329 mgmt_pending_remove(cmd);
1330
1331 return err;
1332}
1333
4e51eae9
SJ
1334static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data,
1335 u16 len)
980e1a53
JH
1336{
1337 struct hci_dev *hdev;
96d97a67 1338 struct hci_conn *conn;
980e1a53 1339 struct mgmt_cp_pin_code_reply *cp;
96d97a67 1340 struct mgmt_cp_pin_code_neg_reply ncp;
980e1a53 1341 struct hci_cp_pin_code_reply reply;
366a0336 1342 struct pending_cmd *cmd;
980e1a53
JH
1343 int err;
1344
1345 BT_DBG("");
1346
1347 cp = (void *) data;
980e1a53 1348
bdce7baf 1349 if (len != sizeof(*cp))
ca69b795
JH
1350 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1351 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1352
4e51eae9 1353 hdev = hci_dev_get(index);
980e1a53 1354 if (!hdev)
ca69b795
JH
1355 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1356 MGMT_STATUS_INVALID_PARAMS);
980e1a53 1357
09fd0de5 1358 hci_dev_lock(hdev);
980e1a53
JH
1359
1360 if (!test_bit(HCI_UP, &hdev->flags)) {
ca69b795
JH
1361 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1362 MGMT_STATUS_NOT_POWERED);
980e1a53
JH
1363 goto failed;
1364 }
1365
96d97a67
WR
1366 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1367 if (!conn) {
ca69b795
JH
1368 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1369 MGMT_STATUS_NOT_CONNECTED);
96d97a67
WR
1370 goto failed;
1371 }
1372
1373 if (conn->pending_sec_level == BT_SECURITY_HIGH && cp->pin_len != 16) {
1374 bacpy(&ncp.bdaddr, &cp->bdaddr);
1375
1376 BT_ERR("PIN code is not 16 bytes long");
1377
1378 err = send_pin_code_neg_reply(sk, index, hdev, &ncp);
1379 if (err >= 0)
1380 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
ca69b795 1381 MGMT_STATUS_INVALID_PARAMS);
96d97a67
WR
1382
1383 goto failed;
1384 }
1385
2e58ef3e 1386 cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, hdev, data, len);
366a0336
JH
1387 if (!cmd) {
1388 err = -ENOMEM;
980e1a53 1389 goto failed;
366a0336 1390 }
980e1a53
JH
1391
1392 bacpy(&reply.bdaddr, &cp->bdaddr);
1393 reply.pin_len = cp->pin_len;
24718ca5 1394 memcpy(reply.pin_code, cp->pin_code, sizeof(reply.pin_code));
980e1a53
JH
1395
1396 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_REPLY, sizeof(reply), &reply);
1397 if (err < 0)
a664b5bc 1398 mgmt_pending_remove(cmd);
980e1a53
JH
1399
1400failed:
09fd0de5 1401 hci_dev_unlock(hdev);
980e1a53
JH
1402 hci_dev_put(hdev);
1403
1404 return err;
1405}
1406
4e51eae9
SJ
1407static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data,
1408 u16 len)
980e1a53
JH
1409{
1410 struct hci_dev *hdev;
1411 struct mgmt_cp_pin_code_neg_reply *cp;
980e1a53
JH
1412 int err;
1413
1414 BT_DBG("");
1415
1416 cp = (void *) data;
980e1a53 1417
bdce7baf
SJ
1418 if (len != sizeof(*cp))
1419 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
ca69b795 1420 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1421
4e51eae9 1422 hdev = hci_dev_get(index);
980e1a53 1423 if (!hdev)
4e51eae9 1424 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
ca69b795 1425 MGMT_STATUS_INVALID_PARAMS);
980e1a53 1426
09fd0de5 1427 hci_dev_lock(hdev);
980e1a53
JH
1428
1429 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9 1430 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
ca69b795 1431 MGMT_STATUS_NOT_POWERED);
980e1a53
JH
1432 goto failed;
1433 }
1434
96d97a67 1435 err = send_pin_code_neg_reply(sk, index, hdev, cp);
980e1a53
JH
1436
1437failed:
09fd0de5 1438 hci_dev_unlock(hdev);
980e1a53
JH
1439 hci_dev_put(hdev);
1440
1441 return err;
1442}
1443
4e51eae9
SJ
1444static int set_io_capability(struct sock *sk, u16 index, unsigned char *data,
1445 u16 len)
17fa4b9d
JH
1446{
1447 struct hci_dev *hdev;
1448 struct mgmt_cp_set_io_capability *cp;
17fa4b9d
JH
1449
1450 BT_DBG("");
1451
1452 cp = (void *) data;
17fa4b9d 1453
bdce7baf 1454 if (len != sizeof(*cp))
ca69b795
JH
1455 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY,
1456 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1457
4e51eae9 1458 hdev = hci_dev_get(index);
17fa4b9d 1459 if (!hdev)
ca69b795
JH
1460 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY,
1461 MGMT_STATUS_INVALID_PARAMS);
17fa4b9d 1462
09fd0de5 1463 hci_dev_lock(hdev);
17fa4b9d
JH
1464
1465 hdev->io_capability = cp->io_capability;
1466
1467 BT_DBG("%s IO capability set to 0x%02x", hdev->name,
b8534e0f 1468 hdev->io_capability);
17fa4b9d 1469
09fd0de5 1470 hci_dev_unlock(hdev);
17fa4b9d
JH
1471 hci_dev_put(hdev);
1472
4e51eae9 1473 return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, NULL, 0);
17fa4b9d
JH
1474}
1475
e9a416b5
JH
1476static inline struct pending_cmd *find_pairing(struct hci_conn *conn)
1477{
1478 struct hci_dev *hdev = conn->hdev;
8035ded4 1479 struct pending_cmd *cmd;
e9a416b5 1480
2e58ef3e 1481 list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
e9a416b5
JH
1482 if (cmd->opcode != MGMT_OP_PAIR_DEVICE)
1483 continue;
1484
e9a416b5
JH
1485 if (cmd->user_data != conn)
1486 continue;
1487
1488 return cmd;
1489 }
1490
1491 return NULL;
1492}
1493
1494static void pairing_complete(struct pending_cmd *cmd, u8 status)
1495{
1496 struct mgmt_rp_pair_device rp;
1497 struct hci_conn *conn = cmd->user_data;
1498
ba4e564f
JH
1499 bacpy(&rp.addr.bdaddr, &conn->dst);
1500 rp.addr.type = link_to_mgmt(conn->type, conn->dst_type);
e9a416b5
JH
1501 rp.status = status;
1502
4e51eae9 1503 cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, &rp, sizeof(rp));
e9a416b5
JH
1504
1505 /* So we don't get further callbacks for this connection */
1506 conn->connect_cfm_cb = NULL;
1507 conn->security_cfm_cb = NULL;
1508 conn->disconn_cfm_cb = NULL;
1509
1510 hci_conn_put(conn);
1511
a664b5bc 1512 mgmt_pending_remove(cmd);
e9a416b5
JH
1513}
1514
1515static void pairing_complete_cb(struct hci_conn *conn, u8 status)
1516{
1517 struct pending_cmd *cmd;
1518
1519 BT_DBG("status %u", status);
1520
1521 cmd = find_pairing(conn);
56e5cb86 1522 if (!cmd)
e9a416b5 1523 BT_DBG("Unable to find a pending command");
56e5cb86
JH
1524 else
1525 pairing_complete(cmd, status);
e9a416b5
JH
1526}
1527
4e51eae9 1528static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len)
e9a416b5
JH
1529{
1530 struct hci_dev *hdev;
1531 struct mgmt_cp_pair_device *cp;
1425acb7 1532 struct mgmt_rp_pair_device rp;
e9a416b5
JH
1533 struct pending_cmd *cmd;
1534 u8 sec_level, auth_type;
1535 struct hci_conn *conn;
e9a416b5
JH
1536 int err;
1537
1538 BT_DBG("");
1539
1540 cp = (void *) data;
e9a416b5 1541
bdce7baf 1542 if (len != sizeof(*cp))
ca69b795
JH
1543 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE,
1544 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1545
4e51eae9 1546 hdev = hci_dev_get(index);
e9a416b5 1547 if (!hdev)
ca69b795
JH
1548 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE,
1549 MGMT_STATUS_INVALID_PARAMS);
e9a416b5 1550
09fd0de5 1551 hci_dev_lock(hdev);
e9a416b5 1552
c908df36
VCG
1553 sec_level = BT_SECURITY_MEDIUM;
1554 if (cp->io_cap == 0x03)
e9a416b5 1555 auth_type = HCI_AT_DEDICATED_BONDING;
c908df36 1556 else
e9a416b5 1557 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
e9a416b5 1558
ba4e564f
JH
1559 if (cp->addr.type == MGMT_ADDR_BREDR)
1560 conn = hci_connect(hdev, ACL_LINK, &cp->addr.bdaddr, sec_level,
7a512d01
VCG
1561 auth_type);
1562 else
ba4e564f 1563 conn = hci_connect(hdev, LE_LINK, &cp->addr.bdaddr, sec_level,
7a512d01
VCG
1564 auth_type);
1565
1425acb7
JH
1566 memset(&rp, 0, sizeof(rp));
1567 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
1568 rp.addr.type = cp->addr.type;
1569
30e76272 1570 if (IS_ERR(conn)) {
1425acb7
JH
1571 rp.status = -PTR_ERR(conn);
1572 err = cmd_complete(sk, index, MGMT_OP_PAIR_DEVICE,
1573 &rp, sizeof(rp));
e9a416b5
JH
1574 goto unlock;
1575 }
1576
1577 if (conn->connect_cfm_cb) {
1578 hci_conn_put(conn);
1425acb7
JH
1579 rp.status = EBUSY;
1580 err = cmd_complete(sk, index, MGMT_OP_PAIR_DEVICE,
1581 &rp, sizeof(rp));
e9a416b5
JH
1582 goto unlock;
1583 }
1584
2e58ef3e 1585 cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, hdev, data, len);
e9a416b5
JH
1586 if (!cmd) {
1587 err = -ENOMEM;
1588 hci_conn_put(conn);
1589 goto unlock;
1590 }
1591
7a512d01 1592 /* For LE, just connecting isn't a proof that the pairing finished */
ba4e564f 1593 if (cp->addr.type == MGMT_ADDR_BREDR)
7a512d01
VCG
1594 conn->connect_cfm_cb = pairing_complete_cb;
1595
e9a416b5
JH
1596 conn->security_cfm_cb = pairing_complete_cb;
1597 conn->disconn_cfm_cb = pairing_complete_cb;
1598 conn->io_capability = cp->io_cap;
1599 cmd->user_data = conn;
1600
1601 if (conn->state == BT_CONNECTED &&
1602 hci_conn_security(conn, sec_level, auth_type))
1603 pairing_complete(cmd, 0);
1604
1605 err = 0;
1606
1607unlock:
09fd0de5 1608 hci_dev_unlock(hdev);
e9a416b5
JH
1609 hci_dev_put(hdev);
1610
1611 return err;
1612}
1613
0df4c185
BG
1614static int user_pairing_resp(struct sock *sk, u16 index, bdaddr_t *bdaddr,
1615 u16 mgmt_op, u16 hci_op, __le32 passkey)
a5c29683 1616{
a5c29683
JH
1617 struct pending_cmd *cmd;
1618 struct hci_dev *hdev;
0df4c185 1619 struct hci_conn *conn;
a5c29683
JH
1620 int err;
1621
4e51eae9 1622 hdev = hci_dev_get(index);
a5c29683 1623 if (!hdev)
ca69b795
JH
1624 return cmd_status(sk, index, mgmt_op,
1625 MGMT_STATUS_INVALID_PARAMS);
a5c29683 1626
09fd0de5 1627 hci_dev_lock(hdev);
08ba5382 1628
a5c29683 1629 if (!test_bit(HCI_UP, &hdev->flags)) {
0df4c185
BG
1630 err = cmd_status(sk, index, mgmt_op, MGMT_STATUS_NOT_POWERED);
1631 goto done;
a5c29683
JH
1632 }
1633
47c15e2b
BG
1634 /*
1635 * Check for an existing ACL link, if present pair via
1636 * HCI commands.
1637 *
1638 * If no ACL link is present, check for an LE link and if
1639 * present, pair via the SMP engine.
1640 *
1641 * If neither ACL nor LE links are present, fail with error.
1642 */
1643 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, bdaddr);
1644 if (!conn) {
1645 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr);
1646 if (!conn) {
1647 err = cmd_status(sk, index, mgmt_op,
1648 MGMT_STATUS_NOT_CONNECTED);
1649 goto done;
1650 }
1651
1652 /* Continue with pairing via SMP */
1653
1654 err = cmd_status(sk, index, mgmt_op, MGMT_STATUS_SUCCESS);
1655 goto done;
1656 }
1657
0df4c185 1658 cmd = mgmt_pending_add(sk, mgmt_op, hdev, bdaddr, sizeof(*bdaddr));
a5c29683
JH
1659 if (!cmd) {
1660 err = -ENOMEM;
0df4c185 1661 goto done;
a5c29683
JH
1662 }
1663
0df4c185 1664 /* Continue with pairing via HCI */
604086b7
BG
1665 if (hci_op == HCI_OP_USER_PASSKEY_REPLY) {
1666 struct hci_cp_user_passkey_reply cp;
1667
1668 bacpy(&cp.bdaddr, bdaddr);
1669 cp.passkey = passkey;
1670 err = hci_send_cmd(hdev, hci_op, sizeof(cp), &cp);
1671 } else
1672 err = hci_send_cmd(hdev, hci_op, sizeof(*bdaddr), bdaddr);
1673
a664b5bc
JH
1674 if (err < 0)
1675 mgmt_pending_remove(cmd);
a5c29683 1676
0df4c185 1677done:
09fd0de5 1678 hci_dev_unlock(hdev);
a5c29683
JH
1679 hci_dev_put(hdev);
1680
1681 return err;
1682}
1683
0df4c185
BG
1684static int user_confirm_reply(struct sock *sk, u16 index, void *data, u16 len)
1685{
1686 struct mgmt_cp_user_confirm_reply *cp = (void *) data;
1687
1688 BT_DBG("");
1689
1690 if (len != sizeof(*cp))
1691 return cmd_status(sk, index, MGMT_OP_USER_CONFIRM_REPLY,
1692 MGMT_STATUS_INVALID_PARAMS);
1693
1694 return user_pairing_resp(sk, index, &cp->bdaddr,
1695 MGMT_OP_USER_CONFIRM_REPLY,
1696 HCI_OP_USER_CONFIRM_REPLY, 0);
1697}
1698
1699static int user_confirm_neg_reply(struct sock *sk, u16 index, void *data,
1700 u16 len)
1701{
1702 struct mgmt_cp_user_confirm_reply *cp = (void *) data;
1703
1704 BT_DBG("");
1705
1706 if (len != sizeof(*cp))
1707 return cmd_status(sk, index, MGMT_OP_USER_CONFIRM_NEG_REPLY,
1708 MGMT_STATUS_INVALID_PARAMS);
1709
1710 return user_pairing_resp(sk, index, &cp->bdaddr,
1711 MGMT_OP_USER_CONFIRM_NEG_REPLY,
1712 HCI_OP_USER_CONFIRM_NEG_REPLY, 0);
1713}
1714
604086b7
BG
1715static int user_passkey_reply(struct sock *sk, u16 index, void *data, u16 len)
1716{
1717 struct mgmt_cp_user_passkey_reply *cp = (void *) data;
1718
1719 BT_DBG("");
1720
1721 if (len != sizeof(*cp))
1722 return cmd_status(sk, index, MGMT_OP_USER_PASSKEY_REPLY,
1723 EINVAL);
1724
1725 return user_pairing_resp(sk, index, &cp->bdaddr,
1726 MGMT_OP_USER_PASSKEY_REPLY,
1727 HCI_OP_USER_PASSKEY_REPLY, cp->passkey);
1728}
1729
1730static int user_passkey_neg_reply(struct sock *sk, u16 index, void *data,
1731 u16 len)
1732{
1733 struct mgmt_cp_user_passkey_neg_reply *cp = (void *) data;
1734
1735 BT_DBG("");
1736
1737 if (len != sizeof(*cp))
1738 return cmd_status(sk, index, MGMT_OP_USER_PASSKEY_NEG_REPLY,
1739 EINVAL);
1740
1741 return user_pairing_resp(sk, index, &cp->bdaddr,
1742 MGMT_OP_USER_PASSKEY_NEG_REPLY,
1743 HCI_OP_USER_PASSKEY_NEG_REPLY, 0);
1744}
1745
b312b161
JH
1746static int set_local_name(struct sock *sk, u16 index, unsigned char *data,
1747 u16 len)
1748{
1749 struct mgmt_cp_set_local_name *mgmt_cp = (void *) data;
1750 struct hci_cp_write_local_name hci_cp;
1751 struct hci_dev *hdev;
1752 struct pending_cmd *cmd;
1753 int err;
1754
1755 BT_DBG("");
1756
1757 if (len != sizeof(*mgmt_cp))
ca69b795
JH
1758 return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME,
1759 MGMT_STATUS_INVALID_PARAMS);
b312b161
JH
1760
1761 hdev = hci_dev_get(index);
1762 if (!hdev)
ca69b795
JH
1763 return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME,
1764 MGMT_STATUS_INVALID_PARAMS);
b312b161 1765
09fd0de5 1766 hci_dev_lock(hdev);
b312b161 1767
2e58ef3e 1768 cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, hdev, data, len);
b312b161
JH
1769 if (!cmd) {
1770 err = -ENOMEM;
1771 goto failed;
1772 }
1773
1774 memcpy(hci_cp.name, mgmt_cp->name, sizeof(hci_cp.name));
1775 err = hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(hci_cp),
1776 &hci_cp);
1777 if (err < 0)
1778 mgmt_pending_remove(cmd);
1779
1780failed:
09fd0de5 1781 hci_dev_unlock(hdev);
b312b161
JH
1782 hci_dev_put(hdev);
1783
1784 return err;
1785}
1786
c35938b2
SJ
1787static int read_local_oob_data(struct sock *sk, u16 index)
1788{
1789 struct hci_dev *hdev;
1790 struct pending_cmd *cmd;
1791 int err;
1792
1793 BT_DBG("hci%u", index);
1794
1795 hdev = hci_dev_get(index);
1796 if (!hdev)
1797 return cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
ca69b795 1798 MGMT_STATUS_INVALID_PARAMS);
c35938b2 1799
09fd0de5 1800 hci_dev_lock(hdev);
c35938b2
SJ
1801
1802 if (!test_bit(HCI_UP, &hdev->flags)) {
1803 err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
ca69b795 1804 MGMT_STATUS_NOT_POWERED);
c35938b2
SJ
1805 goto unlock;
1806 }
1807
1808 if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) {
1809 err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
ca69b795 1810 MGMT_STATUS_NOT_SUPPORTED);
c35938b2
SJ
1811 goto unlock;
1812 }
1813
2e58ef3e 1814 if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev)) {
ca69b795
JH
1815 err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
1816 MGMT_STATUS_BUSY);
c35938b2
SJ
1817 goto unlock;
1818 }
1819
2e58ef3e 1820 cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, hdev, NULL, 0);
c35938b2
SJ
1821 if (!cmd) {
1822 err = -ENOMEM;
1823 goto unlock;
1824 }
1825
1826 err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
1827 if (err < 0)
1828 mgmt_pending_remove(cmd);
1829
1830unlock:
09fd0de5 1831 hci_dev_unlock(hdev);
c35938b2
SJ
1832 hci_dev_put(hdev);
1833
1834 return err;
1835}
1836
2763eda6
SJ
1837static int add_remote_oob_data(struct sock *sk, u16 index, unsigned char *data,
1838 u16 len)
1839{
1840 struct hci_dev *hdev;
1841 struct mgmt_cp_add_remote_oob_data *cp = (void *) data;
1842 int err;
1843
1844 BT_DBG("hci%u ", index);
1845
1846 if (len != sizeof(*cp))
1847 return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
ca69b795 1848 MGMT_STATUS_INVALID_PARAMS);
2763eda6
SJ
1849
1850 hdev = hci_dev_get(index);
1851 if (!hdev)
1852 return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
ca69b795 1853 MGMT_STATUS_INVALID_PARAMS);
2763eda6 1854
09fd0de5 1855 hci_dev_lock(hdev);
2763eda6
SJ
1856
1857 err = hci_add_remote_oob_data(hdev, &cp->bdaddr, cp->hash,
1858 cp->randomizer);
1859 if (err < 0)
ca69b795
JH
1860 err = cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
1861 MGMT_STATUS_FAILED);
2763eda6
SJ
1862 else
1863 err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, NULL,
1864 0);
1865
09fd0de5 1866 hci_dev_unlock(hdev);
2763eda6
SJ
1867 hci_dev_put(hdev);
1868
1869 return err;
1870}
1871
1872static int remove_remote_oob_data(struct sock *sk, u16 index,
1873 unsigned char *data, u16 len)
1874{
1875 struct hci_dev *hdev;
1876 struct mgmt_cp_remove_remote_oob_data *cp = (void *) data;
1877 int err;
1878
1879 BT_DBG("hci%u ", index);
1880
1881 if (len != sizeof(*cp))
1882 return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
ca69b795 1883 MGMT_STATUS_INVALID_PARAMS);
2763eda6
SJ
1884
1885 hdev = hci_dev_get(index);
1886 if (!hdev)
1887 return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
ca69b795 1888 MGMT_STATUS_INVALID_PARAMS);
2763eda6 1889
09fd0de5 1890 hci_dev_lock(hdev);
2763eda6
SJ
1891
1892 err = hci_remove_remote_oob_data(hdev, &cp->bdaddr);
1893 if (err < 0)
1894 err = cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
ca69b795 1895 MGMT_STATUS_INVALID_PARAMS);
2763eda6
SJ
1896 else
1897 err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
1898 NULL, 0);
1899
09fd0de5 1900 hci_dev_unlock(hdev);
2763eda6
SJ
1901 hci_dev_put(hdev);
1902
1903 return err;
1904}
1905
450dfdaf
JH
1906static int start_discovery(struct sock *sk, u16 index,
1907 unsigned char *data, u16 len)
14a53664 1908{
450dfdaf 1909 struct mgmt_cp_start_discovery *cp = (void *) data;
14a53664
JH
1910 struct pending_cmd *cmd;
1911 struct hci_dev *hdev;
1912 int err;
1913
1914 BT_DBG("hci%u", index);
1915
450dfdaf
JH
1916 if (len != sizeof(*cp))
1917 return cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
1918 MGMT_STATUS_INVALID_PARAMS);
1919
14a53664
JH
1920 hdev = hci_dev_get(index);
1921 if (!hdev)
ca69b795
JH
1922 return cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
1923 MGMT_STATUS_INVALID_PARAMS);
14a53664 1924
09fd0de5 1925 hci_dev_lock(hdev);
14a53664 1926
bd2d1334 1927 if (!test_bit(HCI_UP, &hdev->flags)) {
ca69b795
JH
1928 err = cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
1929 MGMT_STATUS_NOT_POWERED);
bd2d1334
JH
1930 goto failed;
1931 }
1932
2e58ef3e 1933 cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, hdev, NULL, 0);
14a53664
JH
1934 if (!cmd) {
1935 err = -ENOMEM;
1936 goto failed;
1937 }
1938
2519a1fc 1939 err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR);
14a53664
JH
1940 if (err < 0)
1941 mgmt_pending_remove(cmd);
1942
1943failed:
09fd0de5 1944 hci_dev_unlock(hdev);
14a53664
JH
1945 hci_dev_put(hdev);
1946
1947 return err;
1948}
1949
1950static int stop_discovery(struct sock *sk, u16 index)
1951{
1952 struct hci_dev *hdev;
1953 struct pending_cmd *cmd;
1954 int err;
1955
1956 BT_DBG("hci%u", index);
1957
1958 hdev = hci_dev_get(index);
1959 if (!hdev)
ca69b795
JH
1960 return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY,
1961 MGMT_STATUS_INVALID_PARAMS);
14a53664 1962
09fd0de5 1963 hci_dev_lock(hdev);
14a53664 1964
2e58ef3e 1965 cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, NULL, 0);
14a53664
JH
1966 if (!cmd) {
1967 err = -ENOMEM;
1968 goto failed;
1969 }
1970
023d5049 1971 err = hci_cancel_inquiry(hdev);
14a53664
JH
1972 if (err < 0)
1973 mgmt_pending_remove(cmd);
1974
1975failed:
09fd0de5 1976 hci_dev_unlock(hdev);
14a53664
JH
1977 hci_dev_put(hdev);
1978
1979 return err;
1980}
1981
7fbec224
AJ
1982static int block_device(struct sock *sk, u16 index, unsigned char *data,
1983 u16 len)
1984{
1985 struct hci_dev *hdev;
5e762444 1986 struct mgmt_cp_block_device *cp = (void *) data;
7fbec224
AJ
1987 int err;
1988
1989 BT_DBG("hci%u", index);
1990
7fbec224
AJ
1991 if (len != sizeof(*cp))
1992 return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
ca69b795 1993 MGMT_STATUS_INVALID_PARAMS);
7fbec224
AJ
1994
1995 hdev = hci_dev_get(index);
1996 if (!hdev)
1997 return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
ca69b795 1998 MGMT_STATUS_INVALID_PARAMS);
7fbec224 1999
09fd0de5 2000 hci_dev_lock(hdev);
5e762444 2001
7fbec224 2002 err = hci_blacklist_add(hdev, &cp->bdaddr);
7fbec224 2003 if (err < 0)
ca69b795
JH
2004 err = cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
2005 MGMT_STATUS_FAILED);
7fbec224
AJ
2006 else
2007 err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE,
2008 NULL, 0);
5e762444 2009
09fd0de5 2010 hci_dev_unlock(hdev);
7fbec224
AJ
2011 hci_dev_put(hdev);
2012
2013 return err;
2014}
2015
2016static int unblock_device(struct sock *sk, u16 index, unsigned char *data,
2017 u16 len)
2018{
2019 struct hci_dev *hdev;
5e762444 2020 struct mgmt_cp_unblock_device *cp = (void *) data;
7fbec224
AJ
2021 int err;
2022
2023 BT_DBG("hci%u", index);
2024
7fbec224
AJ
2025 if (len != sizeof(*cp))
2026 return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
ca69b795 2027 MGMT_STATUS_INVALID_PARAMS);
7fbec224
AJ
2028
2029 hdev = hci_dev_get(index);
2030 if (!hdev)
2031 return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
ca69b795 2032 MGMT_STATUS_INVALID_PARAMS);
7fbec224 2033
09fd0de5 2034 hci_dev_lock(hdev);
5e762444 2035
7fbec224
AJ
2036 err = hci_blacklist_del(hdev, &cp->bdaddr);
2037
2038 if (err < 0)
ca69b795
JH
2039 err = cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
2040 MGMT_STATUS_INVALID_PARAMS);
7fbec224
AJ
2041 else
2042 err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE,
2043 NULL, 0);
5e762444 2044
09fd0de5 2045 hci_dev_unlock(hdev);
7fbec224
AJ
2046 hci_dev_put(hdev);
2047
2048 return err;
2049}
2050
f6422ec6
AJ
2051static int set_fast_connectable(struct sock *sk, u16 index,
2052 unsigned char *data, u16 len)
2053{
2054 struct hci_dev *hdev;
f7c6869c 2055 struct mgmt_mode *cp = (void *) data;
f6422ec6
AJ
2056 struct hci_cp_write_page_scan_activity acp;
2057 u8 type;
2058 int err;
2059
2060 BT_DBG("hci%u", index);
2061
2062 if (len != sizeof(*cp))
2063 return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2064 MGMT_STATUS_INVALID_PARAMS);
f6422ec6
AJ
2065
2066 hdev = hci_dev_get(index);
2067 if (!hdev)
2068 return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2069 MGMT_STATUS_INVALID_PARAMS);
f6422ec6
AJ
2070
2071 hci_dev_lock(hdev);
2072
f7c6869c 2073 if (cp->val) {
f6422ec6
AJ
2074 type = PAGE_SCAN_TYPE_INTERLACED;
2075 acp.interval = 0x0024; /* 22.5 msec page scan interval */
2076 } else {
2077 type = PAGE_SCAN_TYPE_STANDARD; /* default */
2078 acp.interval = 0x0800; /* default 1.28 sec page scan */
2079 }
2080
2081 acp.window = 0x0012; /* default 11.25 msec page scan window */
2082
2083 err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
2084 sizeof(acp), &acp);
2085 if (err < 0) {
2086 err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2087 MGMT_STATUS_FAILED);
f6422ec6
AJ
2088 goto done;
2089 }
2090
2091 err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type);
2092 if (err < 0) {
2093 err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2094 MGMT_STATUS_FAILED);
f6422ec6
AJ
2095 goto done;
2096 }
2097
2098 err = cmd_complete(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
2099 NULL, 0);
2100done:
2101 hci_dev_unlock(hdev);
2102 hci_dev_put(hdev);
2103
2104 return err;
2105}
2106
0381101f
JH
2107int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
2108{
2109 unsigned char *buf;
2110 struct mgmt_hdr *hdr;
4e51eae9 2111 u16 opcode, index, len;
0381101f
JH
2112 int err;
2113
2114 BT_DBG("got %zu bytes", msglen);
2115
2116 if (msglen < sizeof(*hdr))
2117 return -EINVAL;
2118
e63a15ec 2119 buf = kmalloc(msglen, GFP_KERNEL);
0381101f
JH
2120 if (!buf)
2121 return -ENOMEM;
2122
2123 if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
2124 err = -EFAULT;
2125 goto done;
2126 }
2127
2128 hdr = (struct mgmt_hdr *) buf;
2129 opcode = get_unaligned_le16(&hdr->opcode);
4e51eae9 2130 index = get_unaligned_le16(&hdr->index);
0381101f
JH
2131 len = get_unaligned_le16(&hdr->len);
2132
2133 if (len != msglen - sizeof(*hdr)) {
2134 err = -EINVAL;
2135 goto done;
2136 }
2137
2138 switch (opcode) {
02d98129
JH
2139 case MGMT_OP_READ_VERSION:
2140 err = read_version(sk);
2141 break;
faba42eb
JH
2142 case MGMT_OP_READ_INDEX_LIST:
2143 err = read_index_list(sk);
2144 break;
f7b64e69 2145 case MGMT_OP_READ_INFO:
4e51eae9 2146 err = read_controller_info(sk, index);
f7b64e69 2147 break;
eec8d2bc 2148 case MGMT_OP_SET_POWERED:
4e51eae9 2149 err = set_powered(sk, index, buf + sizeof(*hdr), len);
eec8d2bc 2150 break;
73f22f62 2151 case MGMT_OP_SET_DISCOVERABLE:
4e51eae9 2152 err = set_discoverable(sk, index, buf + sizeof(*hdr), len);
73f22f62 2153 break;
9fbcbb45 2154 case MGMT_OP_SET_CONNECTABLE:
4e51eae9 2155 err = set_connectable(sk, index, buf + sizeof(*hdr), len);
9fbcbb45 2156 break;
f7c6869c
JH
2157 case MGMT_OP_SET_FAST_CONNECTABLE:
2158 err = set_fast_connectable(sk, index, buf + sizeof(*hdr),
2159 len);
2160 break;
c542a06c 2161 case MGMT_OP_SET_PAIRABLE:
4e51eae9 2162 err = set_pairable(sk, index, buf + sizeof(*hdr), len);
c542a06c 2163 break;
2aeb9a1a 2164 case MGMT_OP_ADD_UUID:
4e51eae9 2165 err = add_uuid(sk, index, buf + sizeof(*hdr), len);
2aeb9a1a
JH
2166 break;
2167 case MGMT_OP_REMOVE_UUID:
4e51eae9 2168 err = remove_uuid(sk, index, buf + sizeof(*hdr), len);
2aeb9a1a 2169 break;
1aff6f09 2170 case MGMT_OP_SET_DEV_CLASS:
4e51eae9 2171 err = set_dev_class(sk, index, buf + sizeof(*hdr), len);
1aff6f09
JH
2172 break;
2173 case MGMT_OP_SET_SERVICE_CACHE:
4e51eae9 2174 err = set_service_cache(sk, index, buf + sizeof(*hdr), len);
1aff6f09 2175 break;
86742e1e
JH
2176 case MGMT_OP_LOAD_LINK_KEYS:
2177 err = load_link_keys(sk, index, buf + sizeof(*hdr), len);
55ed8ca1 2178 break;
86742e1e
JH
2179 case MGMT_OP_REMOVE_KEYS:
2180 err = remove_keys(sk, index, buf + sizeof(*hdr), len);
55ed8ca1 2181 break;
8962ee74 2182 case MGMT_OP_DISCONNECT:
4e51eae9 2183 err = disconnect(sk, index, buf + sizeof(*hdr), len);
8962ee74 2184 break;
2784eb41 2185 case MGMT_OP_GET_CONNECTIONS:
8ce6284e 2186 err = get_connections(sk, index);
2784eb41 2187 break;
980e1a53 2188 case MGMT_OP_PIN_CODE_REPLY:
4e51eae9 2189 err = pin_code_reply(sk, index, buf + sizeof(*hdr), len);
980e1a53
JH
2190 break;
2191 case MGMT_OP_PIN_CODE_NEG_REPLY:
4e51eae9 2192 err = pin_code_neg_reply(sk, index, buf + sizeof(*hdr), len);
980e1a53 2193 break;
17fa4b9d 2194 case MGMT_OP_SET_IO_CAPABILITY:
4e51eae9 2195 err = set_io_capability(sk, index, buf + sizeof(*hdr), len);
17fa4b9d 2196 break;
e9a416b5 2197 case MGMT_OP_PAIR_DEVICE:
4e51eae9 2198 err = pair_device(sk, index, buf + sizeof(*hdr), len);
e9a416b5 2199 break;
a5c29683 2200 case MGMT_OP_USER_CONFIRM_REPLY:
0df4c185 2201 err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len);
a5c29683
JH
2202 break;
2203 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
0df4c185
BG
2204 err = user_confirm_neg_reply(sk, index, buf + sizeof(*hdr),
2205 len);
a5c29683 2206 break;
604086b7
BG
2207 case MGMT_OP_USER_PASSKEY_REPLY:
2208 err = user_passkey_reply(sk, index, buf + sizeof(*hdr), len);
2209 break;
2210 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
2211 err = user_passkey_neg_reply(sk, index, buf + sizeof(*hdr),
2212 len);
2213 break;
b312b161
JH
2214 case MGMT_OP_SET_LOCAL_NAME:
2215 err = set_local_name(sk, index, buf + sizeof(*hdr), len);
2216 break;
c35938b2
SJ
2217 case MGMT_OP_READ_LOCAL_OOB_DATA:
2218 err = read_local_oob_data(sk, index);
2219 break;
2763eda6
SJ
2220 case MGMT_OP_ADD_REMOTE_OOB_DATA:
2221 err = add_remote_oob_data(sk, index, buf + sizeof(*hdr), len);
2222 break;
2223 case MGMT_OP_REMOVE_REMOTE_OOB_DATA:
2224 err = remove_remote_oob_data(sk, index, buf + sizeof(*hdr),
2225 len);
2226 break;
14a53664 2227 case MGMT_OP_START_DISCOVERY:
450dfdaf 2228 err = start_discovery(sk, index, buf + sizeof(*hdr), len);
14a53664
JH
2229 break;
2230 case MGMT_OP_STOP_DISCOVERY:
2231 err = stop_discovery(sk, index);
2232 break;
7fbec224
AJ
2233 case MGMT_OP_BLOCK_DEVICE:
2234 err = block_device(sk, index, buf + sizeof(*hdr), len);
2235 break;
2236 case MGMT_OP_UNBLOCK_DEVICE:
2237 err = unblock_device(sk, index, buf + sizeof(*hdr), len);
2238 break;
0381101f
JH
2239 default:
2240 BT_DBG("Unknown op %u", opcode);
ca69b795
JH
2241 err = cmd_status(sk, index, opcode,
2242 MGMT_STATUS_UNKNOWN_COMMAND);
0381101f
JH
2243 break;
2244 }
2245
e41d8b4e
JH
2246 if (err < 0)
2247 goto done;
2248
0381101f
JH
2249 err = msglen;
2250
2251done:
2252 kfree(buf);
2253 return err;
2254}
c71e97bf 2255
b24752fe
JH
2256static void cmd_status_rsp(struct pending_cmd *cmd, void *data)
2257{
2258 u8 *status = data;
2259
2260 cmd_status(cmd->sk, cmd->index, cmd->opcode, *status);
2261 mgmt_pending_remove(cmd);
2262}
2263
744cf19e 2264int mgmt_index_added(struct hci_dev *hdev)
c71e97bf 2265{
744cf19e 2266 return mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL);
c71e97bf
JH
2267}
2268
744cf19e 2269int mgmt_index_removed(struct hci_dev *hdev)
c71e97bf 2270{
b24752fe
JH
2271 u8 status = ENODEV;
2272
744cf19e 2273 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
b24752fe 2274
744cf19e 2275 return mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL);
eec8d2bc
JH
2276}
2277
73f22f62 2278struct cmd_lookup {
72a734ec 2279 u8 val;
eec8d2bc 2280 struct sock *sk;
69ab39ea 2281 struct hci_dev *hdev;
eec8d2bc
JH
2282};
2283
69ab39ea 2284static void settings_rsp(struct pending_cmd *cmd, void *data)
eec8d2bc 2285{
73f22f62 2286 struct cmd_lookup *match = data;
eec8d2bc 2287
69ab39ea 2288 send_settings_rsp(cmd->sk, cmd->opcode, match->hdev);
eec8d2bc
JH
2289
2290 list_del(&cmd->list);
2291
2292 if (match->sk == NULL) {
2293 match->sk = cmd->sk;
2294 sock_hold(match->sk);
2295 }
2296
2297 mgmt_pending_free(cmd);
c71e97bf 2298}
5add6af8 2299
744cf19e 2300int mgmt_powered(struct hci_dev *hdev, u8 powered)
5add6af8 2301{
69ab39ea
JH
2302 struct cmd_lookup match = { powered, NULL, hdev };
2303 __le32 ev;
eec8d2bc 2304 int ret;
5add6af8 2305
69ab39ea 2306 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
5add6af8 2307
b24752fe
JH
2308 if (!powered) {
2309 u8 status = ENETDOWN;
744cf19e 2310 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
b24752fe
JH
2311 }
2312
69ab39ea 2313 ev = cpu_to_le32(get_current_settings(hdev));
eec8d2bc 2314
69ab39ea
JH
2315 ret = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev),
2316 match.sk);
eec8d2bc
JH
2317
2318 if (match.sk)
2319 sock_put(match.sk);
2320
2321 return ret;
5add6af8 2322}
73f22f62 2323
744cf19e 2324int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
73f22f62 2325{
69ab39ea
JH
2326 struct cmd_lookup match = { discoverable, NULL, hdev };
2327 __le32 ev;
73f22f62
JH
2328 int ret;
2329
69ab39ea 2330 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, settings_rsp, &match);
72a734ec 2331
69ab39ea 2332 ev = cpu_to_le32(get_current_settings(hdev));
73f22f62 2333
69ab39ea 2334 ret = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev),
4e51eae9 2335 match.sk);
73f22f62
JH
2336 if (match.sk)
2337 sock_put(match.sk);
2338
2339 return ret;
2340}
9fbcbb45 2341
744cf19e 2342int mgmt_connectable(struct hci_dev *hdev, u8 connectable)
9fbcbb45 2343{
69ab39ea
JH
2344 __le32 ev;
2345 struct cmd_lookup match = { connectable, NULL, hdev };
9fbcbb45
JH
2346 int ret;
2347
69ab39ea
JH
2348 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, settings_rsp,
2349 &match);
9fbcbb45 2350
69ab39ea 2351 ev = cpu_to_le32(get_current_settings(hdev));
9fbcbb45 2352
69ab39ea 2353 ret = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), match.sk);
9fbcbb45
JH
2354
2355 if (match.sk)
2356 sock_put(match.sk);
2357
2358 return ret;
2359}
55ed8ca1 2360
744cf19e 2361int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status)
2d7cee58 2362{
ca69b795
JH
2363 u8 mgmt_err = mgmt_status(status);
2364
2d7cee58 2365 if (scan & SCAN_PAGE)
744cf19e 2366 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev,
ca69b795 2367 cmd_status_rsp, &mgmt_err);
2d7cee58
JH
2368
2369 if (scan & SCAN_INQUIRY)
744cf19e 2370 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev,
ca69b795 2371 cmd_status_rsp, &mgmt_err);
2d7cee58
JH
2372
2373 return 0;
2374}
2375
744cf19e
JH
2376int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
2377 u8 persistent)
55ed8ca1 2378{
86742e1e 2379 struct mgmt_ev_new_link_key ev;
55ed8ca1 2380
a492cd52 2381 memset(&ev, 0, sizeof(ev));
55ed8ca1 2382
a492cd52
VCG
2383 ev.store_hint = persistent;
2384 bacpy(&ev.key.bdaddr, &key->bdaddr);
2385 ev.key.type = key->type;
2386 memcpy(ev.key.val, key->val, 16);
2387 ev.key.pin_len = key->pin_len;
55ed8ca1 2388
744cf19e 2389 return mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL);
55ed8ca1 2390}
f7520543 2391
48264f06
JH
2392int mgmt_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
2393 u8 addr_type)
f7520543 2394{
4c659c39 2395 struct mgmt_addr_info ev;
f7520543 2396
f7520543 2397 bacpy(&ev.bdaddr, bdaddr);
48264f06 2398 ev.type = link_to_mgmt(link_type, addr_type);
f7520543 2399
744cf19e 2400 return mgmt_event(MGMT_EV_CONNECTED, hdev, &ev, sizeof(ev), NULL);
f7520543
JH
2401}
2402
8962ee74
JH
2403static void disconnect_rsp(struct pending_cmd *cmd, void *data)
2404{
c68fb7ff 2405 struct mgmt_cp_disconnect *cp = cmd->param;
8962ee74 2406 struct sock **sk = data;
a38528f1 2407 struct mgmt_rp_disconnect rp;
8962ee74 2408
a38528f1 2409 bacpy(&rp.bdaddr, &cp->bdaddr);
37d9ef76 2410 rp.status = 0;
8962ee74 2411
4e51eae9 2412 cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, &rp, sizeof(rp));
8962ee74
JH
2413
2414 *sk = cmd->sk;
2415 sock_hold(*sk);
2416
a664b5bc 2417 mgmt_pending_remove(cmd);
8962ee74
JH
2418}
2419
a8a1d19e
JH
2420static void remove_keys_rsp(struct pending_cmd *cmd, void *data)
2421{
2422 u8 *status = data;
2423 struct mgmt_cp_remove_keys *cp = cmd->param;
2424 struct mgmt_rp_remove_keys rp;
2425
2426 memset(&rp, 0, sizeof(rp));
2427 bacpy(&rp.bdaddr, &cp->bdaddr);
2428 if (status != NULL)
2429 rp.status = *status;
2430
2431 cmd_complete(cmd->sk, cmd->index, MGMT_OP_REMOVE_KEYS, &rp,
2432 sizeof(rp));
2433
2434 mgmt_pending_remove(cmd);
2435}
2436
48264f06
JH
2437int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
2438 u8 addr_type)
f7520543 2439{
4c659c39 2440 struct mgmt_addr_info ev;
8962ee74
JH
2441 struct sock *sk = NULL;
2442 int err;
2443
744cf19e 2444 mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk);
f7520543 2445
f7520543 2446 bacpy(&ev.bdaddr, bdaddr);
48264f06 2447 ev.type = link_to_mgmt(link_type, addr_type);
f7520543 2448
744cf19e 2449 err = mgmt_event(MGMT_EV_DISCONNECTED, hdev, &ev, sizeof(ev), sk);
8962ee74
JH
2450
2451 if (sk)
2452 sock_put(sk);
2453
a8a1d19e
JH
2454 mgmt_pending_foreach(MGMT_OP_REMOVE_KEYS, hdev, remove_keys_rsp, NULL);
2455
8962ee74
JH
2456 return err;
2457}
2458
37d9ef76 2459int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status)
8962ee74
JH
2460{
2461 struct pending_cmd *cmd;
ca69b795 2462 u8 mgmt_err = mgmt_status(status);
8962ee74
JH
2463 int err;
2464
2e58ef3e 2465 cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev);
8962ee74
JH
2466 if (!cmd)
2467 return -ENOENT;
2468
37d9ef76
JH
2469 if (bdaddr) {
2470 struct mgmt_rp_disconnect rp;
2471
2472 bacpy(&rp.bdaddr, bdaddr);
2473 rp.status = status;
2474
2475 err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT,
2476 &rp, sizeof(rp));
2477 } else
2478 err = cmd_status(cmd->sk, hdev->id, MGMT_OP_DISCONNECT,
ca69b795 2479 mgmt_err);
8962ee74 2480
a664b5bc 2481 mgmt_pending_remove(cmd);
8962ee74
JH
2482
2483 return err;
f7520543 2484}
17d5c04c 2485
48264f06
JH
2486int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
2487 u8 addr_type, u8 status)
17d5c04c
JH
2488{
2489 struct mgmt_ev_connect_failed ev;
2490
4c659c39 2491 bacpy(&ev.addr.bdaddr, bdaddr);
48264f06 2492 ev.addr.type = link_to_mgmt(link_type, addr_type);
ca69b795 2493 ev.status = mgmt_status(status);
17d5c04c 2494
744cf19e 2495 return mgmt_event(MGMT_EV_CONNECT_FAILED, hdev, &ev, sizeof(ev), NULL);
17d5c04c 2496}
980e1a53 2497
744cf19e 2498int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure)
980e1a53
JH
2499{
2500 struct mgmt_ev_pin_code_request ev;
2501
980e1a53 2502 bacpy(&ev.bdaddr, bdaddr);
a770bb5a 2503 ev.secure = secure;
980e1a53 2504
744cf19e 2505 return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, hdev, &ev, sizeof(ev),
4e51eae9 2506 NULL);
980e1a53
JH
2507}
2508
744cf19e
JH
2509int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
2510 u8 status)
980e1a53
JH
2511{
2512 struct pending_cmd *cmd;
ac56fb13 2513 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
2514 int err;
2515
2e58ef3e 2516 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev);
980e1a53
JH
2517 if (!cmd)
2518 return -ENOENT;
2519
ac56fb13 2520 bacpy(&rp.bdaddr, bdaddr);
ca69b795 2521 rp.status = mgmt_status(status);
ac56fb13 2522
744cf19e 2523 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, &rp,
4e51eae9 2524 sizeof(rp));
980e1a53 2525
a664b5bc 2526 mgmt_pending_remove(cmd);
980e1a53
JH
2527
2528 return err;
2529}
2530
744cf19e
JH
2531int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
2532 u8 status)
980e1a53
JH
2533{
2534 struct pending_cmd *cmd;
ac56fb13 2535 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
2536 int err;
2537
2e58ef3e 2538 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev);
980e1a53
JH
2539 if (!cmd)
2540 return -ENOENT;
2541
ac56fb13 2542 bacpy(&rp.bdaddr, bdaddr);
ca69b795 2543 rp.status = mgmt_status(status);
ac56fb13 2544
744cf19e 2545 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY, &rp,
4e51eae9 2546 sizeof(rp));
980e1a53 2547
a664b5bc 2548 mgmt_pending_remove(cmd);
980e1a53
JH
2549
2550 return err;
2551}
a5c29683 2552
744cf19e
JH
2553int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
2554 __le32 value, u8 confirm_hint)
a5c29683
JH
2555{
2556 struct mgmt_ev_user_confirm_request ev;
2557
744cf19e 2558 BT_DBG("%s", hdev->name);
a5c29683 2559
a5c29683 2560 bacpy(&ev.bdaddr, bdaddr);
55bc1a37 2561 ev.confirm_hint = confirm_hint;
a5c29683
JH
2562 put_unaligned_le32(value, &ev.value);
2563
744cf19e 2564 return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, hdev, &ev, sizeof(ev),
4e51eae9 2565 NULL);
a5c29683
JH
2566}
2567
604086b7
BG
2568int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr)
2569{
2570 struct mgmt_ev_user_passkey_request ev;
2571
2572 BT_DBG("%s", hdev->name);
2573
2574 bacpy(&ev.bdaddr, bdaddr);
2575
2576 return mgmt_event(MGMT_EV_USER_PASSKEY_REQUEST, hdev, &ev, sizeof(ev),
2577 NULL);
2578}
2579
0df4c185 2580static int user_pairing_resp_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
744cf19e 2581 u8 status, u8 opcode)
a5c29683
JH
2582{
2583 struct pending_cmd *cmd;
2584 struct mgmt_rp_user_confirm_reply rp;
2585 int err;
2586
2e58ef3e 2587 cmd = mgmt_pending_find(opcode, hdev);
a5c29683
JH
2588 if (!cmd)
2589 return -ENOENT;
2590
a5c29683 2591 bacpy(&rp.bdaddr, bdaddr);
ca69b795 2592 rp.status = mgmt_status(status);
744cf19e 2593 err = cmd_complete(cmd->sk, hdev->id, opcode, &rp, sizeof(rp));
a5c29683 2594
a664b5bc 2595 mgmt_pending_remove(cmd);
a5c29683
JH
2596
2597 return err;
2598}
2599
744cf19e
JH
2600int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
2601 u8 status)
a5c29683 2602{
0df4c185 2603 return user_pairing_resp_complete(hdev, bdaddr, status,
a5c29683
JH
2604 MGMT_OP_USER_CONFIRM_REPLY);
2605}
2606
744cf19e
JH
2607int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev,
2608 bdaddr_t *bdaddr, u8 status)
a5c29683 2609{
0df4c185 2610 return user_pairing_resp_complete(hdev, bdaddr, status,
a5c29683
JH
2611 MGMT_OP_USER_CONFIRM_NEG_REPLY);
2612}
2a611692 2613
604086b7
BG
2614int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
2615 u8 status)
2616{
2617 return user_pairing_resp_complete(hdev, bdaddr, status,
2618 MGMT_OP_USER_PASSKEY_REPLY);
2619}
2620
2621int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev,
2622 bdaddr_t *bdaddr, u8 status)
2623{
2624 return user_pairing_resp_complete(hdev, bdaddr, status,
2625 MGMT_OP_USER_PASSKEY_NEG_REPLY);
2626}
2627
744cf19e 2628int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status)
2a611692
JH
2629{
2630 struct mgmt_ev_auth_failed ev;
2631
2a611692 2632 bacpy(&ev.bdaddr, bdaddr);
ca69b795 2633 ev.status = mgmt_status(status);
2a611692 2634
744cf19e 2635 return mgmt_event(MGMT_EV_AUTH_FAILED, hdev, &ev, sizeof(ev), NULL);
2a611692 2636}
b312b161 2637
744cf19e 2638int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status)
b312b161
JH
2639{
2640 struct pending_cmd *cmd;
2641 struct mgmt_cp_set_local_name ev;
2642 int err;
2643
2644 memset(&ev, 0, sizeof(ev));
2645 memcpy(ev.name, name, HCI_MAX_NAME_LENGTH);
2646
2e58ef3e 2647 cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev);
b312b161
JH
2648 if (!cmd)
2649 goto send_event;
2650
2651 if (status) {
744cf19e 2652 err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
ca69b795 2653 mgmt_status(status));
b312b161
JH
2654 goto failed;
2655 }
2656
744cf19e 2657 update_eir(hdev);
80a1e1db 2658
744cf19e 2659 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, &ev,
b312b161
JH
2660 sizeof(ev));
2661 if (err < 0)
2662 goto failed;
2663
2664send_event:
744cf19e 2665 err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev),
b312b161
JH
2666 cmd ? cmd->sk : NULL);
2667
2668failed:
2669 if (cmd)
2670 mgmt_pending_remove(cmd);
2671 return err;
2672}
c35938b2 2673
744cf19e
JH
2674int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
2675 u8 *randomizer, u8 status)
c35938b2
SJ
2676{
2677 struct pending_cmd *cmd;
2678 int err;
2679
744cf19e 2680 BT_DBG("%s status %u", hdev->name, status);
c35938b2 2681
2e58ef3e 2682 cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev);
c35938b2
SJ
2683 if (!cmd)
2684 return -ENOENT;
2685
2686 if (status) {
744cf19e 2687 err = cmd_status(cmd->sk, hdev->id,
ca69b795
JH
2688 MGMT_OP_READ_LOCAL_OOB_DATA,
2689 mgmt_status(status));
c35938b2
SJ
2690 } else {
2691 struct mgmt_rp_read_local_oob_data rp;
2692
2693 memcpy(rp.hash, hash, sizeof(rp.hash));
2694 memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer));
2695
744cf19e
JH
2696 err = cmd_complete(cmd->sk, hdev->id,
2697 MGMT_OP_READ_LOCAL_OOB_DATA,
2698 &rp, sizeof(rp));
c35938b2
SJ
2699 }
2700
2701 mgmt_pending_remove(cmd);
2702
2703 return err;
2704}
e17acd40 2705
48264f06
JH
2706int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
2707 u8 addr_type, u8 *dev_class, s8 rssi, u8 *eir)
e17acd40
JH
2708{
2709 struct mgmt_ev_device_found ev;
2710
2711 memset(&ev, 0, sizeof(ev));
2712
4c659c39 2713 bacpy(&ev.addr.bdaddr, bdaddr);
48264f06 2714 ev.addr.type = link_to_mgmt(link_type, addr_type);
e17acd40
JH
2715 ev.rssi = rssi;
2716
2717 if (eir)
2718 memcpy(ev.eir, eir, sizeof(ev.eir));
2719
f8523598
AG
2720 if (dev_class)
2721 memcpy(ev.dev_class, dev_class, sizeof(ev.dev_class));
2722
744cf19e 2723 return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, &ev, sizeof(ev), NULL);
e17acd40 2724}
a88a9652 2725
744cf19e 2726int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name)
a88a9652
JH
2727{
2728 struct mgmt_ev_remote_name ev;
2729
2730 memset(&ev, 0, sizeof(ev));
2731
2732 bacpy(&ev.bdaddr, bdaddr);
2733 memcpy(ev.name, name, HCI_MAX_NAME_LENGTH);
2734
744cf19e 2735 return mgmt_event(MGMT_EV_REMOTE_NAME, hdev, &ev, sizeof(ev), NULL);
a88a9652 2736}
314b2381 2737
7a135109 2738int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status)
164a6e78
JH
2739{
2740 struct pending_cmd *cmd;
2741 int err;
2742
2e58ef3e 2743 cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev);
164a6e78
JH
2744 if (!cmd)
2745 return -ENOENT;
2746
ca69b795 2747 err = cmd_status(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status));
164a6e78
JH
2748 mgmt_pending_remove(cmd);
2749
2750 return err;
2751}
2752
e6d465cb
AG
2753int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status)
2754{
2755 struct pending_cmd *cmd;
2756 int err;
2757
2758 cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev);
2759 if (!cmd)
2760 return -ENOENT;
2761
2762 err = cmd_status(cmd->sk, hdev->id, cmd->opcode, status);
2763 mgmt_pending_remove(cmd);
2764
2765 return err;
2766}
2767
744cf19e 2768int mgmt_discovering(struct hci_dev *hdev, u8 discovering)
314b2381 2769{
164a6e78
JH
2770 struct pending_cmd *cmd;
2771
2772 if (discovering)
2e58ef3e 2773 cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev);
164a6e78 2774 else
2e58ef3e 2775 cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev);
164a6e78
JH
2776
2777 if (cmd != NULL) {
744cf19e 2778 cmd_complete(cmd->sk, hdev->id, cmd->opcode, NULL, 0);
164a6e78
JH
2779 mgmt_pending_remove(cmd);
2780 }
2781
744cf19e 2782 return mgmt_event(MGMT_EV_DISCOVERING, hdev, &discovering,
314b2381
JH
2783 sizeof(discovering), NULL);
2784}
5e762444 2785
744cf19e 2786int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr)
5e762444
AJ
2787{
2788 struct pending_cmd *cmd;
2789 struct mgmt_ev_device_blocked ev;
2790
2e58ef3e 2791 cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, hdev);
5e762444
AJ
2792
2793 bacpy(&ev.bdaddr, bdaddr);
2794
744cf19e
JH
2795 return mgmt_event(MGMT_EV_DEVICE_BLOCKED, hdev, &ev, sizeof(ev),
2796 cmd ? cmd->sk : NULL);
5e762444
AJ
2797}
2798
744cf19e 2799int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr)
5e762444
AJ
2800{
2801 struct pending_cmd *cmd;
2802 struct mgmt_ev_device_unblocked ev;
2803
2e58ef3e 2804 cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, hdev);
5e762444
AJ
2805
2806 bacpy(&ev.bdaddr, bdaddr);
2807
744cf19e
JH
2808 return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &ev, sizeof(ev),
2809 cmd ? cmd->sk : NULL);
5e762444 2810}