]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - net/bluetooth/mgmt.c
Bluetooth: mgmt: Move service cache setting to a more sensible place
[mirror_ubuntu-artful-kernel.git] / net / bluetooth / mgmt.c
CommitLineData
0381101f
JH
1/*
2 BlueZ - Bluetooth protocol stack for Linux
ea585ab5 3
0381101f 4 Copyright (C) 2010 Nokia Corporation
ea585ab5 5 Copyright (C) 2011-2012 Intel Corporation
0381101f
JH
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
15 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
22 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI Management interface */
26
ca69b795 27#include <linux/kernel.h>
72359753 28#include <linux/uaccess.h>
3a9a231d 29#include <linux/module.h>
0381101f
JH
30#include <asm/unaligned.h>
31
32#include <net/bluetooth/bluetooth.h>
33#include <net/bluetooth/hci_core.h>
34#include <net/bluetooth/mgmt.h>
5fe57d9e 35#include <net/bluetooth/smp.h>
0381101f 36
d7b7e796
MH
37bool enable_hs;
38bool enable_le;
39
2da9c55c
JH
40#define MGMT_VERSION 1
41#define MGMT_REVISION 0
02d98129 42
e70bb2e8
JH
43static const u16 mgmt_commands[] = {
44 MGMT_OP_READ_INDEX_LIST,
45 MGMT_OP_READ_INFO,
46 MGMT_OP_SET_POWERED,
47 MGMT_OP_SET_DISCOVERABLE,
48 MGMT_OP_SET_CONNECTABLE,
49 MGMT_OP_SET_FAST_CONNECTABLE,
50 MGMT_OP_SET_PAIRABLE,
51 MGMT_OP_SET_LINK_SECURITY,
52 MGMT_OP_SET_SSP,
53 MGMT_OP_SET_HS,
54 MGMT_OP_SET_LE,
55 MGMT_OP_SET_DEV_CLASS,
56 MGMT_OP_SET_LOCAL_NAME,
57 MGMT_OP_ADD_UUID,
58 MGMT_OP_REMOVE_UUID,
59 MGMT_OP_LOAD_LINK_KEYS,
60 MGMT_OP_LOAD_LONG_TERM_KEYS,
61 MGMT_OP_DISCONNECT,
62 MGMT_OP_GET_CONNECTIONS,
63 MGMT_OP_PIN_CODE_REPLY,
64 MGMT_OP_PIN_CODE_NEG_REPLY,
65 MGMT_OP_SET_IO_CAPABILITY,
66 MGMT_OP_PAIR_DEVICE,
67 MGMT_OP_CANCEL_PAIR_DEVICE,
68 MGMT_OP_UNPAIR_DEVICE,
69 MGMT_OP_USER_CONFIRM_REPLY,
70 MGMT_OP_USER_CONFIRM_NEG_REPLY,
71 MGMT_OP_USER_PASSKEY_REPLY,
72 MGMT_OP_USER_PASSKEY_NEG_REPLY,
73 MGMT_OP_READ_LOCAL_OOB_DATA,
74 MGMT_OP_ADD_REMOTE_OOB_DATA,
75 MGMT_OP_REMOVE_REMOTE_OOB_DATA,
76 MGMT_OP_START_DISCOVERY,
77 MGMT_OP_STOP_DISCOVERY,
78 MGMT_OP_CONFIRM_NAME,
79 MGMT_OP_BLOCK_DEVICE,
80 MGMT_OP_UNBLOCK_DEVICE,
81};
82
83static const u16 mgmt_events[] = {
84 MGMT_EV_CONTROLLER_ERROR,
85 MGMT_EV_INDEX_ADDED,
86 MGMT_EV_INDEX_REMOVED,
87 MGMT_EV_NEW_SETTINGS,
88 MGMT_EV_CLASS_OF_DEV_CHANGED,
89 MGMT_EV_LOCAL_NAME_CHANGED,
90 MGMT_EV_NEW_LINK_KEY,
91 MGMT_EV_NEW_LONG_TERM_KEY,
92 MGMT_EV_DEVICE_CONNECTED,
93 MGMT_EV_DEVICE_DISCONNECTED,
94 MGMT_EV_CONNECT_FAILED,
95 MGMT_EV_PIN_CODE_REQUEST,
96 MGMT_EV_USER_CONFIRM_REQUEST,
97 MGMT_EV_USER_PASSKEY_REQUEST,
98 MGMT_EV_AUTH_FAILED,
99 MGMT_EV_DEVICE_FOUND,
100 MGMT_EV_DISCOVERING,
101 MGMT_EV_DEVICE_BLOCKED,
102 MGMT_EV_DEVICE_UNBLOCKED,
103 MGMT_EV_DEVICE_UNPAIRED,
104};
105
3fd24153
AG
106/*
107 * These LE scan and inquiry parameters were chosen according to LE General
108 * Discovery Procedure specification.
109 */
110#define LE_SCAN_TYPE 0x01
111#define LE_SCAN_WIN 0x12
112#define LE_SCAN_INT 0x12
113#define LE_SCAN_TIMEOUT_LE_ONLY 10240 /* TGAP(gen_disc_scan_min) */
5e0452c0 114#define LE_SCAN_TIMEOUT_BREDR_LE 5120 /* TGAP(100)/2 */
3fd24153 115
e8777525 116#define INQUIRY_LEN_BREDR 0x08 /* TGAP(100) */
5e0452c0 117#define INQUIRY_LEN_BREDR_LE 0x04 /* TGAP(100)/2 */
2519a1fc 118
7d78525d
JH
119#define SERVICE_CACHE_TIMEOUT (5 * 1000)
120
4b34ee78
JH
121#define hdev_is_powered(hdev) (test_bit(HCI_UP, &hdev->flags) && \
122 !test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
123
eec8d2bc
JH
124struct pending_cmd {
125 struct list_head list;
fc2f4b13 126 u16 opcode;
eec8d2bc 127 int index;
c68fb7ff 128 void *param;
eec8d2bc 129 struct sock *sk;
e9a416b5 130 void *user_data;
eec8d2bc
JH
131};
132
ca69b795
JH
133/* HCI to MGMT error code conversion table */
134static u8 mgmt_status_table[] = {
135 MGMT_STATUS_SUCCESS,
136 MGMT_STATUS_UNKNOWN_COMMAND, /* Unknown Command */
137 MGMT_STATUS_NOT_CONNECTED, /* No Connection */
138 MGMT_STATUS_FAILED, /* Hardware Failure */
139 MGMT_STATUS_CONNECT_FAILED, /* Page Timeout */
140 MGMT_STATUS_AUTH_FAILED, /* Authentication Failed */
141 MGMT_STATUS_NOT_PAIRED, /* PIN or Key Missing */
142 MGMT_STATUS_NO_RESOURCES, /* Memory Full */
143 MGMT_STATUS_TIMEOUT, /* Connection Timeout */
144 MGMT_STATUS_NO_RESOURCES, /* Max Number of Connections */
145 MGMT_STATUS_NO_RESOURCES, /* Max Number of SCO Connections */
146 MGMT_STATUS_ALREADY_CONNECTED, /* ACL Connection Exists */
147 MGMT_STATUS_BUSY, /* Command Disallowed */
148 MGMT_STATUS_NO_RESOURCES, /* Rejected Limited Resources */
149 MGMT_STATUS_REJECTED, /* Rejected Security */
150 MGMT_STATUS_REJECTED, /* Rejected Personal */
151 MGMT_STATUS_TIMEOUT, /* Host Timeout */
152 MGMT_STATUS_NOT_SUPPORTED, /* Unsupported Feature */
153 MGMT_STATUS_INVALID_PARAMS, /* Invalid Parameters */
154 MGMT_STATUS_DISCONNECTED, /* OE User Ended Connection */
155 MGMT_STATUS_NO_RESOURCES, /* OE Low Resources */
156 MGMT_STATUS_DISCONNECTED, /* OE Power Off */
157 MGMT_STATUS_DISCONNECTED, /* Connection Terminated */
158 MGMT_STATUS_BUSY, /* Repeated Attempts */
159 MGMT_STATUS_REJECTED, /* Pairing Not Allowed */
160 MGMT_STATUS_FAILED, /* Unknown LMP PDU */
161 MGMT_STATUS_NOT_SUPPORTED, /* Unsupported Remote Feature */
162 MGMT_STATUS_REJECTED, /* SCO Offset Rejected */
163 MGMT_STATUS_REJECTED, /* SCO Interval Rejected */
164 MGMT_STATUS_REJECTED, /* Air Mode Rejected */
165 MGMT_STATUS_INVALID_PARAMS, /* Invalid LMP Parameters */
166 MGMT_STATUS_FAILED, /* Unspecified Error */
167 MGMT_STATUS_NOT_SUPPORTED, /* Unsupported LMP Parameter Value */
168 MGMT_STATUS_FAILED, /* Role Change Not Allowed */
169 MGMT_STATUS_TIMEOUT, /* LMP Response Timeout */
170 MGMT_STATUS_FAILED, /* LMP Error Transaction Collision */
171 MGMT_STATUS_FAILED, /* LMP PDU Not Allowed */
172 MGMT_STATUS_REJECTED, /* Encryption Mode Not Accepted */
173 MGMT_STATUS_FAILED, /* Unit Link Key Used */
174 MGMT_STATUS_NOT_SUPPORTED, /* QoS Not Supported */
175 MGMT_STATUS_TIMEOUT, /* Instant Passed */
176 MGMT_STATUS_NOT_SUPPORTED, /* Pairing Not Supported */
177 MGMT_STATUS_FAILED, /* Transaction Collision */
178 MGMT_STATUS_INVALID_PARAMS, /* Unacceptable Parameter */
179 MGMT_STATUS_REJECTED, /* QoS Rejected */
180 MGMT_STATUS_NOT_SUPPORTED, /* Classification Not Supported */
181 MGMT_STATUS_REJECTED, /* Insufficient Security */
182 MGMT_STATUS_INVALID_PARAMS, /* Parameter Out Of Range */
183 MGMT_STATUS_BUSY, /* Role Switch Pending */
184 MGMT_STATUS_FAILED, /* Slot Violation */
185 MGMT_STATUS_FAILED, /* Role Switch Failed */
186 MGMT_STATUS_INVALID_PARAMS, /* EIR Too Large */
187 MGMT_STATUS_NOT_SUPPORTED, /* Simple Pairing Not Supported */
188 MGMT_STATUS_BUSY, /* Host Busy Pairing */
189 MGMT_STATUS_REJECTED, /* Rejected, No Suitable Channel */
190 MGMT_STATUS_BUSY, /* Controller Busy */
191 MGMT_STATUS_INVALID_PARAMS, /* Unsuitable Connection Interval */
192 MGMT_STATUS_TIMEOUT, /* Directed Advertising Timeout */
193 MGMT_STATUS_AUTH_FAILED, /* Terminated Due to MIC Failure */
194 MGMT_STATUS_CONNECT_FAILED, /* Connection Establishment Failed */
195 MGMT_STATUS_CONNECT_FAILED, /* MAC Connection Failed */
196};
197
198static u8 mgmt_status(u8 hci_status)
199{
200 if (hci_status < ARRAY_SIZE(mgmt_status_table))
201 return mgmt_status_table[hci_status];
202
203 return MGMT_STATUS_FAILED;
204}
205
4e51eae9 206static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
f7b64e69
JH
207{
208 struct sk_buff *skb;
209 struct mgmt_hdr *hdr;
210 struct mgmt_ev_cmd_status *ev;
56b7d137 211 int err;
f7b64e69 212
34eb525c 213 BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status);
f7b64e69
JH
214
215 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC);
216 if (!skb)
217 return -ENOMEM;
218
219 hdr = (void *) skb_put(skb, sizeof(*hdr));
220
221 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS);
4e51eae9 222 hdr->index = cpu_to_le16(index);
f7b64e69
JH
223 hdr->len = cpu_to_le16(sizeof(*ev));
224
225 ev = (void *) skb_put(skb, sizeof(*ev));
226 ev->status = status;
227 put_unaligned_le16(cmd, &ev->opcode);
228
56b7d137
GP
229 err = sock_queue_rcv_skb(sk, skb);
230 if (err < 0)
f7b64e69
JH
231 kfree_skb(skb);
232
56b7d137 233 return err;
f7b64e69
JH
234}
235
aee9b218
JH
236static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status,
237 void *rp, size_t rp_len)
02d98129
JH
238{
239 struct sk_buff *skb;
240 struct mgmt_hdr *hdr;
241 struct mgmt_ev_cmd_complete *ev;
56b7d137 242 int err;
02d98129
JH
243
244 BT_DBG("sock %p", sk);
245
a38528f1 246 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_ATOMIC);
02d98129
JH
247 if (!skb)
248 return -ENOMEM;
249
250 hdr = (void *) skb_put(skb, sizeof(*hdr));
02d98129 251
a38528f1 252 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
4e51eae9 253 hdr->index = cpu_to_le16(index);
a38528f1 254 hdr->len = cpu_to_le16(sizeof(*ev) + rp_len);
02d98129 255
a38528f1
JH
256 ev = (void *) skb_put(skb, sizeof(*ev) + rp_len);
257 put_unaligned_le16(cmd, &ev->opcode);
aee9b218 258 ev->status = status;
8020c16a
SJ
259
260 if (rp)
261 memcpy(ev->data, rp, rp_len);
02d98129 262
56b7d137
GP
263 err = sock_queue_rcv_skb(sk, skb);
264 if (err < 0)
02d98129
JH
265 kfree_skb(skb);
266
e5f0e151 267 return err;
02d98129
JH
268}
269
a38528f1
JH
270static int read_version(struct sock *sk)
271{
272 struct mgmt_rp_read_version rp;
273
274 BT_DBG("sock %p", sk);
275
276 rp.version = MGMT_VERSION;
277 put_unaligned_le16(MGMT_REVISION, &rp.revision);
278
aee9b218 279 return cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_VERSION, 0, &rp,
4e51eae9 280 sizeof(rp));
a38528f1
JH
281}
282
e70bb2e8
JH
283static int read_commands(struct sock *sk)
284{
285 struct mgmt_rp_read_commands *rp;
286 u16 num_commands = ARRAY_SIZE(mgmt_commands);
287 u16 num_events = ARRAY_SIZE(mgmt_events);
288 u16 *opcode;
289 size_t rp_size;
290 int i, err;
291
292 BT_DBG("sock %p", sk);
293
294 rp_size = sizeof(*rp) + ((num_commands + num_events) * sizeof(u16));
295
296 rp = kmalloc(rp_size, GFP_KERNEL);
297 if (!rp)
298 return -ENOMEM;
299
300 put_unaligned_le16(num_commands, &rp->num_commands);
301 put_unaligned_le16(num_events, &rp->num_events);
302
303 for (i = 0, opcode = rp->opcodes; i < num_commands; i++, opcode++)
304 put_unaligned_le16(mgmt_commands[i], opcode);
305
306 for (i = 0; i < num_events; i++, opcode++)
307 put_unaligned_le16(mgmt_events[i], opcode);
308
aee9b218 309 err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_COMMANDS, 0, rp,
e70bb2e8
JH
310 rp_size);
311 kfree(rp);
312
313 return err;
314}
315
faba42eb
JH
316static int read_index_list(struct sock *sk)
317{
faba42eb
JH
318 struct mgmt_rp_read_index_list *rp;
319 struct list_head *p;
8035ded4 320 struct hci_dev *d;
a38528f1 321 size_t rp_len;
faba42eb 322 u16 count;
a38528f1 323 int i, err;
faba42eb
JH
324
325 BT_DBG("sock %p", sk);
326
327 read_lock(&hci_dev_list_lock);
328
329 count = 0;
330 list_for_each(p, &hci_dev_list) {
331 count++;
332 }
333
a38528f1
JH
334 rp_len = sizeof(*rp) + (2 * count);
335 rp = kmalloc(rp_len, GFP_ATOMIC);
336 if (!rp) {
b2c60d42 337 read_unlock(&hci_dev_list_lock);
faba42eb 338 return -ENOMEM;
b2c60d42 339 }
faba42eb 340
faba42eb
JH
341 put_unaligned_le16(count, &rp->num_controllers);
342
343 i = 0;
8035ded4 344 list_for_each_entry(d, &hci_dev_list, list) {
a8b2d5c2 345 if (test_bit(HCI_SETUP, &d->dev_flags))
ab81cbf9
JH
346 continue;
347
faba42eb
JH
348 put_unaligned_le16(d->id, &rp->index[i++]);
349 BT_DBG("Added hci%u", d->id);
350 }
351
352 read_unlock(&hci_dev_list_lock);
353
aee9b218 354 err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp,
4e51eae9 355 rp_len);
faba42eb 356
a38528f1
JH
357 kfree(rp);
358
359 return err;
faba42eb
JH
360}
361
69ab39ea
JH
362static u32 get_supported_settings(struct hci_dev *hdev)
363{
364 u32 settings = 0;
365
366 settings |= MGMT_SETTING_POWERED;
367 settings |= MGMT_SETTING_CONNECTABLE;
368 settings |= MGMT_SETTING_FAST_CONNECTABLE;
369 settings |= MGMT_SETTING_DISCOVERABLE;
370 settings |= MGMT_SETTING_PAIRABLE;
371
372 if (hdev->features[6] & LMP_SIMPLE_PAIR)
373 settings |= MGMT_SETTING_SSP;
374
375 if (!(hdev->features[4] & LMP_NO_BREDR)) {
376 settings |= MGMT_SETTING_BREDR;
377 settings |= MGMT_SETTING_LINK_SECURITY;
378 }
379
d7b7e796
MH
380 if (enable_hs)
381 settings |= MGMT_SETTING_HS;
382
383 if (enable_le) {
384 if (hdev->features[4] & LMP_LE)
385 settings |= MGMT_SETTING_LE;
386 }
69ab39ea
JH
387
388 return settings;
389}
390
391static u32 get_current_settings(struct hci_dev *hdev)
392{
393 u32 settings = 0;
394
f1f0eb02 395 if (hdev_is_powered(hdev))
f0d4b78a
MH
396 settings |= MGMT_SETTING_POWERED;
397
5e5282bb 398 if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
69ab39ea
JH
399 settings |= MGMT_SETTING_CONNECTABLE;
400
5e5282bb 401 if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
69ab39ea
JH
402 settings |= MGMT_SETTING_DISCOVERABLE;
403
a8b2d5c2 404 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags))
69ab39ea
JH
405 settings |= MGMT_SETTING_PAIRABLE;
406
407 if (!(hdev->features[4] & LMP_NO_BREDR))
408 settings |= MGMT_SETTING_BREDR;
409
06199cf8 410 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags))
69ab39ea
JH
411 settings |= MGMT_SETTING_LE;
412
47990ea0 413 if (test_bit(HCI_LINK_SECURITY, &hdev->dev_flags))
69ab39ea
JH
414 settings |= MGMT_SETTING_LINK_SECURITY;
415
84bde9d6 416 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
69ab39ea
JH
417 settings |= MGMT_SETTING_SSP;
418
6d80dfd0
JH
419 if (test_bit(HCI_HS_ENABLED, &hdev->dev_flags))
420 settings |= MGMT_SETTING_HS;
421
69ab39ea
JH
422 return settings;
423}
424
ef580372
JH
425#define PNP_INFO_SVCLASS_ID 0x1200
426
427static u8 bluetooth_base_uuid[] = {
428 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
429 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430};
431
432static u16 get_uuid16(u8 *uuid128)
433{
434 u32 val;
435 int i;
436
437 for (i = 0; i < 12; i++) {
438 if (bluetooth_base_uuid[i] != uuid128[i])
439 return 0;
440 }
441
442 memcpy(&val, &uuid128[12], 4);
443
444 val = le32_to_cpu(val);
445 if (val > 0xffff)
446 return 0;
447
448 return (u16) val;
449}
450
451static void create_eir(struct hci_dev *hdev, u8 *data)
452{
453 u8 *ptr = data;
454 u16 eir_len = 0;
455 u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)];
456 int i, truncated = 0;
457 struct bt_uuid *uuid;
458 size_t name_len;
459
460 name_len = strlen(hdev->dev_name);
461
462 if (name_len > 0) {
463 /* EIR Data type */
464 if (name_len > 48) {
465 name_len = 48;
466 ptr[1] = EIR_NAME_SHORT;
467 } else
468 ptr[1] = EIR_NAME_COMPLETE;
469
470 /* EIR Data length */
471 ptr[0] = name_len + 1;
472
473 memcpy(ptr + 2, hdev->dev_name, name_len);
474
475 eir_len += (name_len + 2);
476 ptr += (name_len + 2);
477 }
478
479 memset(uuid16_list, 0, sizeof(uuid16_list));
480
481 /* Group all UUID16 types */
482 list_for_each_entry(uuid, &hdev->uuids, list) {
483 u16 uuid16;
484
485 uuid16 = get_uuid16(uuid->uuid);
486 if (uuid16 == 0)
487 return;
488
489 if (uuid16 < 0x1100)
490 continue;
491
492 if (uuid16 == PNP_INFO_SVCLASS_ID)
493 continue;
494
495 /* Stop if not enough space to put next UUID */
496 if (eir_len + 2 + sizeof(u16) > HCI_MAX_EIR_LENGTH) {
497 truncated = 1;
498 break;
499 }
500
501 /* Check for duplicates */
502 for (i = 0; uuid16_list[i] != 0; i++)
503 if (uuid16_list[i] == uuid16)
504 break;
505
506 if (uuid16_list[i] == 0) {
507 uuid16_list[i] = uuid16;
508 eir_len += sizeof(u16);
509 }
510 }
511
512 if (uuid16_list[0] != 0) {
513 u8 *length = ptr;
514
515 /* EIR Data type */
516 ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL;
517
518 ptr += 2;
519 eir_len += 2;
520
521 for (i = 0; uuid16_list[i] != 0; i++) {
522 *ptr++ = (uuid16_list[i] & 0x00ff);
523 *ptr++ = (uuid16_list[i] & 0xff00) >> 8;
524 }
525
526 /* EIR Data length */
527 *length = (i * sizeof(u16)) + 1;
528 }
529}
530
531static int update_eir(struct hci_dev *hdev)
532{
533 struct hci_cp_write_eir cp;
534
504c8dcd 535 if (!hdev_is_powered(hdev))
7770c4aa
JH
536 return 0;
537
ef580372
JH
538 if (!(hdev->features[6] & LMP_EXT_INQ))
539 return 0;
540
84bde9d6 541 if (!test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
ef580372
JH
542 return 0;
543
a8b2d5c2 544 if (test_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
ef580372
JH
545 return 0;
546
547 memset(&cp, 0, sizeof(cp));
548
549 create_eir(hdev, cp.data);
550
551 if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0)
552 return 0;
553
554 memcpy(hdev->eir, cp.data, sizeof(cp.data));
555
556 return hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
557}
558
559static u8 get_service_classes(struct hci_dev *hdev)
560{
561 struct bt_uuid *uuid;
562 u8 val = 0;
563
564 list_for_each_entry(uuid, &hdev->uuids, list)
565 val |= uuid->svc_hint;
566
567 return val;
568}
569
570static int update_class(struct hci_dev *hdev)
571{
572 u8 cod[3];
573
574 BT_DBG("%s", hdev->name);
575
504c8dcd 576 if (!hdev_is_powered(hdev))
7770c4aa
JH
577 return 0;
578
a8b2d5c2 579 if (test_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
ef580372
JH
580 return 0;
581
582 cod[0] = hdev->minor_class;
583 cod[1] = hdev->major_class;
584 cod[2] = get_service_classes(hdev);
585
586 if (memcmp(cod, hdev->dev_class, 3) == 0)
587 return 0;
588
589 return hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
590}
591
7d78525d
JH
592static void service_cache_off(struct work_struct *work)
593{
594 struct hci_dev *hdev = container_of(work, struct hci_dev,
595 service_cache.work);
596
a8b2d5c2 597 if (!test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
7d78525d
JH
598 return;
599
600 hci_dev_lock(hdev);
601
602 update_eir(hdev);
603 update_class(hdev);
604
605 hci_dev_unlock(hdev);
606}
607
608static void mgmt_init_hdev(struct hci_dev *hdev)
609{
0cbf4ed6 610 if (!test_and_set_bit(HCI_MGMT, &hdev->dev_flags)) {
7d78525d
JH
611 INIT_DELAYED_WORK(&hdev->service_cache, service_cache_off);
612
0cbf4ed6
JH
613 /* Non-mgmt controlled devices get this bit set
614 * implicitly so that pairing works for them, however
615 * for mgmt we require user-space to explicitly enable
616 * it
617 */
618 clear_bit(HCI_PAIRABLE, &hdev->dev_flags);
619 }
7d78525d
JH
620}
621
4e51eae9 622static int read_controller_info(struct sock *sk, u16 index)
0381101f 623{
a38528f1 624 struct mgmt_rp_read_info rp;
f7b64e69 625 struct hci_dev *hdev;
0381101f 626
4e51eae9 627 BT_DBG("sock %p hci%u", sk, index);
f7b64e69 628
4e51eae9 629 hdev = hci_dev_get(index);
a38528f1 630 if (!hdev)
ca69b795
JH
631 return cmd_status(sk, index, MGMT_OP_READ_INFO,
632 MGMT_STATUS_INVALID_PARAMS);
f7b64e69 633
09fd0de5 634 hci_dev_lock(hdev);
f7b64e69 635
7d78525d
JH
636 if (test_and_clear_bit(HCI_PI_MGMT_INIT, &hci_pi(sk)->flags))
637 mgmt_init_hdev(hdev);
ebc99feb 638
dc4fe30b
JH
639 memset(&rp, 0, sizeof(rp));
640
69ab39ea 641 bacpy(&rp.bdaddr, &hdev->bdaddr);
f7b64e69 642
69ab39ea 643 rp.version = hdev->hci_ver;
f7b64e69 644
69ab39ea
JH
645 put_unaligned_le16(hdev->manufacturer, &rp.manufacturer);
646
647 rp.supported_settings = cpu_to_le32(get_supported_settings(hdev));
648 rp.current_settings = cpu_to_le32(get_current_settings(hdev));
f7b64e69 649
a38528f1 650 memcpy(rp.dev_class, hdev->dev_class, 3);
f7b64e69 651
dc4fe30b 652 memcpy(rp.name, hdev->dev_name, sizeof(hdev->dev_name));
27fcc362 653 memcpy(rp.short_name, hdev->short_name, sizeof(hdev->short_name));
dc4fe30b 654
09fd0de5 655 hci_dev_unlock(hdev);
f7b64e69 656 hci_dev_put(hdev);
0381101f 657
aee9b218 658 return cmd_complete(sk, index, MGMT_OP_READ_INFO, 0, &rp, sizeof(rp));
0381101f
JH
659}
660
eec8d2bc
JH
661static void mgmt_pending_free(struct pending_cmd *cmd)
662{
663 sock_put(cmd->sk);
c68fb7ff 664 kfree(cmd->param);
eec8d2bc
JH
665 kfree(cmd);
666}
667
366a0336 668static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
2e58ef3e
JH
669 struct hci_dev *hdev,
670 void *data, u16 len)
eec8d2bc
JH
671{
672 struct pending_cmd *cmd;
673
674 cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
675 if (!cmd)
366a0336 676 return NULL;
eec8d2bc
JH
677
678 cmd->opcode = opcode;
2e58ef3e 679 cmd->index = hdev->id;
eec8d2bc 680
c68fb7ff
SJ
681 cmd->param = kmalloc(len, GFP_ATOMIC);
682 if (!cmd->param) {
eec8d2bc 683 kfree(cmd);
366a0336 684 return NULL;
eec8d2bc
JH
685 }
686
8fce6357
SJ
687 if (data)
688 memcpy(cmd->param, data, len);
eec8d2bc
JH
689
690 cmd->sk = sk;
691 sock_hold(sk);
692
2e58ef3e 693 list_add(&cmd->list, &hdev->mgmt_pending);
eec8d2bc 694
366a0336 695 return cmd;
eec8d2bc
JH
696}
697
744cf19e 698static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev,
eec8d2bc
JH
699 void (*cb)(struct pending_cmd *cmd, void *data),
700 void *data)
701{
702 struct list_head *p, *n;
703
2e58ef3e 704 list_for_each_safe(p, n, &hdev->mgmt_pending) {
eec8d2bc
JH
705 struct pending_cmd *cmd;
706
707 cmd = list_entry(p, struct pending_cmd, list);
708
b24752fe 709 if (opcode > 0 && cmd->opcode != opcode)
eec8d2bc
JH
710 continue;
711
eec8d2bc
JH
712 cb(cmd, data);
713 }
714}
715
2e58ef3e 716static struct pending_cmd *mgmt_pending_find(u16 opcode, struct hci_dev *hdev)
eec8d2bc 717{
8035ded4 718 struct pending_cmd *cmd;
eec8d2bc 719
2e58ef3e 720 list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
2aeabcbe
JH
721 if (cmd->opcode == opcode)
722 return cmd;
eec8d2bc
JH
723 }
724
725 return NULL;
726}
727
a664b5bc 728static void mgmt_pending_remove(struct pending_cmd *cmd)
73f22f62 729{
73f22f62
JH
730 list_del(&cmd->list);
731 mgmt_pending_free(cmd);
732}
733
69ab39ea 734static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev)
8680570b 735{
69ab39ea 736 __le32 settings = cpu_to_le32(get_current_settings(hdev));
8680570b 737
aee9b218
JH
738 return cmd_complete(sk, hdev->id, opcode, 0, &settings,
739 sizeof(settings));
8680570b
JH
740}
741
650f726d 742static int set_powered(struct sock *sk, u16 index, void *data, u16 len)
eec8d2bc 743{
650f726d 744 struct mgmt_mode *cp = data;
eec8d2bc 745 struct hci_dev *hdev;
366a0336 746 struct pending_cmd *cmd;
4b34ee78 747 int err;
eec8d2bc 748
4e51eae9 749 BT_DBG("request for hci%u", index);
eec8d2bc 750
bdce7baf 751 if (len != sizeof(*cp))
ca69b795
JH
752 return cmd_status(sk, index, MGMT_OP_SET_POWERED,
753 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 754
4e51eae9 755 hdev = hci_dev_get(index);
eec8d2bc 756 if (!hdev)
ca69b795
JH
757 return cmd_status(sk, index, MGMT_OP_SET_POWERED,
758 MGMT_STATUS_INVALID_PARAMS);
eec8d2bc 759
09fd0de5 760 hci_dev_lock(hdev);
eec8d2bc 761
f0d4b78a
MH
762 if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
763 cancel_delayed_work(&hdev->power_off);
764
765 if (cp->val) {
766 err = send_settings_rsp(sk, MGMT_OP_SET_POWERED, hdev);
767 mgmt_powered(hdev, 1);
768 goto failed;
769 }
770 }
771
4b34ee78 772 if (!!cp->val == hdev_is_powered(hdev)) {
69ab39ea 773 err = send_settings_rsp(sk, MGMT_OP_SET_POWERED, hdev);
eec8d2bc
JH
774 goto failed;
775 }
776
2e58ef3e 777 if (mgmt_pending_find(MGMT_OP_SET_POWERED, hdev)) {
ca69b795
JH
778 err = cmd_status(sk, index, MGMT_OP_SET_POWERED,
779 MGMT_STATUS_BUSY);
eec8d2bc
JH
780 goto failed;
781 }
782
2e58ef3e 783 cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, hdev, data, len);
366a0336
JH
784 if (!cmd) {
785 err = -ENOMEM;
eec8d2bc 786 goto failed;
366a0336 787 }
eec8d2bc 788
72a734ec 789 if (cp->val)
7f971041 790 schedule_work(&hdev->power_on);
eec8d2bc 791 else
80b7ab33 792 schedule_work(&hdev->power_off.work);
eec8d2bc 793
366a0336 794 err = 0;
eec8d2bc
JH
795
796failed:
09fd0de5 797 hci_dev_unlock(hdev);
eec8d2bc 798 hci_dev_put(hdev);
366a0336 799 return err;
eec8d2bc
JH
800}
801
beadb2bd
JH
802static int mgmt_event(u16 event, struct hci_dev *hdev, void *data,
803 u16 data_len, struct sock *skip_sk)
804{
805 struct sk_buff *skb;
806 struct mgmt_hdr *hdr;
807
808 skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC);
809 if (!skb)
810 return -ENOMEM;
811
812 hdr = (void *) skb_put(skb, sizeof(*hdr));
813 hdr->opcode = cpu_to_le16(event);
814 if (hdev)
815 hdr->index = cpu_to_le16(hdev->id);
816 else
817 hdr->index = cpu_to_le16(MGMT_INDEX_NONE);
818 hdr->len = cpu_to_le16(data_len);
819
820 if (data)
821 memcpy(skb_put(skb, data_len), data, data_len);
822
97e0bdeb
MH
823 /* Time stamp */
824 __net_timestamp(skb);
825
beadb2bd
JH
826 hci_send_to_control(skb, skip_sk);
827 kfree_skb(skb);
828
829 return 0;
830}
831
832static int new_settings(struct hci_dev *hdev, struct sock *skip)
833{
834 __le32 ev;
835
836 ev = cpu_to_le32(get_current_settings(hdev));
837
838 return mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), skip);
839}
840
650f726d 841static int set_discoverable(struct sock *sk, u16 index, void *data, u16 len)
73f22f62 842{
650f726d 843 struct mgmt_cp_set_discoverable *cp = data;
73f22f62 844 struct hci_dev *hdev;
366a0336 845 struct pending_cmd *cmd;
5e5282bb 846 u16 timeout;
73f22f62
JH
847 u8 scan;
848 int err;
849
4e51eae9 850 BT_DBG("request for hci%u", index);
73f22f62 851
bdce7baf 852 if (len != sizeof(*cp))
ca69b795
JH
853 return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE,
854 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 855
24c54a90
MH
856 timeout = get_unaligned_le16(&cp->timeout);
857 if (!cp->val && timeout > 0)
858 return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE,
859 MGMT_STATUS_INVALID_PARAMS);
860
4e51eae9 861 hdev = hci_dev_get(index);
73f22f62 862 if (!hdev)
ca69b795
JH
863 return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE,
864 MGMT_STATUS_INVALID_PARAMS);
73f22f62 865
09fd0de5 866 hci_dev_lock(hdev);
73f22f62 867
5e5282bb 868 if (!hdev_is_powered(hdev) && timeout > 0) {
ca69b795
JH
869 err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE,
870 MGMT_STATUS_NOT_POWERED);
73f22f62
JH
871 goto failed;
872 }
873
2e58ef3e
JH
874 if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) ||
875 mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) {
ca69b795
JH
876 err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE,
877 MGMT_STATUS_BUSY);
73f22f62
JH
878 goto failed;
879 }
880
5e5282bb
JH
881 if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) {
882 err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE,
883 MGMT_STATUS_REJECTED);
884 goto failed;
885 }
886
887 if (!hdev_is_powered(hdev)) {
0224d2fa
JH
888 bool changed = false;
889
890 if (!!cp->val != test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) {
891 change_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
892 changed = true;
893 }
894
5e5282bb 895 err = send_settings_rsp(sk, MGMT_OP_SET_DISCOVERABLE, hdev);
0224d2fa
JH
896 if (err < 0)
897 goto failed;
898
899 if (changed)
900 err = new_settings(hdev, sk);
901
5e5282bb
JH
902 goto failed;
903 }
904
905 if (!!cp->val == test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) {
955638ec
MH
906 if (hdev->discov_timeout > 0) {
907 cancel_delayed_work(&hdev->discov_off);
908 hdev->discov_timeout = 0;
909 }
910
911 if (cp->val && timeout > 0) {
912 hdev->discov_timeout = timeout;
913 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
914 msecs_to_jiffies(hdev->discov_timeout * 1000));
915 }
916
69ab39ea 917 err = send_settings_rsp(sk, MGMT_OP_SET_DISCOVERABLE, hdev);
73f22f62
JH
918 goto failed;
919 }
920
2e58ef3e 921 cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, hdev, data, len);
366a0336
JH
922 if (!cmd) {
923 err = -ENOMEM;
73f22f62 924 goto failed;
366a0336 925 }
73f22f62
JH
926
927 scan = SCAN_PAGE;
928
72a734ec 929 if (cp->val)
73f22f62 930 scan |= SCAN_INQUIRY;
16ab91ab 931 else
e0f9309f 932 cancel_delayed_work(&hdev->discov_off);
73f22f62
JH
933
934 err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
935 if (err < 0)
a664b5bc 936 mgmt_pending_remove(cmd);
73f22f62 937
16ab91ab 938 if (cp->val)
5e5282bb 939 hdev->discov_timeout = timeout;
16ab91ab 940
73f22f62 941failed:
09fd0de5 942 hci_dev_unlock(hdev);
73f22f62
JH
943 hci_dev_put(hdev);
944
945 return err;
946}
947
650f726d 948static int set_connectable(struct sock *sk, u16 index, void *data, u16 len)
9fbcbb45 949{
650f726d 950 struct mgmt_mode *cp = data;
9fbcbb45 951 struct hci_dev *hdev;
366a0336 952 struct pending_cmd *cmd;
9fbcbb45
JH
953 u8 scan;
954 int err;
955
4e51eae9 956 BT_DBG("request for hci%u", index);
9fbcbb45 957
bdce7baf 958 if (len != sizeof(*cp))
ca69b795
JH
959 return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE,
960 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 961
4e51eae9 962 hdev = hci_dev_get(index);
9fbcbb45 963 if (!hdev)
ca69b795
JH
964 return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE,
965 MGMT_STATUS_INVALID_PARAMS);
9fbcbb45 966
09fd0de5 967 hci_dev_lock(hdev);
9fbcbb45 968
4b34ee78 969 if (!hdev_is_powered(hdev)) {
0224d2fa
JH
970 bool changed = false;
971
972 if (!!cp->val != test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
973 changed = true;
974
6bf0e469 975 if (cp->val) {
5e5282bb 976 set_bit(HCI_CONNECTABLE, &hdev->dev_flags);
6bf0e469 977 } else {
5e5282bb
JH
978 clear_bit(HCI_CONNECTABLE, &hdev->dev_flags);
979 clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags);
980 }
0224d2fa 981
5e5282bb 982 err = send_settings_rsp(sk, MGMT_OP_SET_CONNECTABLE, hdev);
0224d2fa
JH
983 if (err < 0)
984 goto failed;
985
986 if (changed)
987 err = new_settings(hdev, sk);
988
9fbcbb45
JH
989 goto failed;
990 }
991
2e58ef3e
JH
992 if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) ||
993 mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) {
ca69b795
JH
994 err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE,
995 MGMT_STATUS_BUSY);
9fbcbb45
JH
996 goto failed;
997 }
998
5e5282bb 999 if (!!cp->val == test_bit(HCI_PSCAN, &hdev->flags)) {
69ab39ea 1000 err = send_settings_rsp(sk, MGMT_OP_SET_CONNECTABLE, hdev);
9fbcbb45
JH
1001 goto failed;
1002 }
1003
2e58ef3e 1004 cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, hdev, data, len);
366a0336
JH
1005 if (!cmd) {
1006 err = -ENOMEM;
9fbcbb45 1007 goto failed;
366a0336 1008 }
9fbcbb45 1009
6bf0e469 1010 if (cp->val) {
9fbcbb45 1011 scan = SCAN_PAGE;
6bf0e469 1012 } else {
9fbcbb45
JH
1013 scan = 0;
1014
df2c6c5e
JH
1015 if (test_bit(HCI_ISCAN, &hdev->flags) &&
1016 hdev->discov_timeout > 0)
1017 cancel_delayed_work(&hdev->discov_off);
1018 }
1019
9fbcbb45
JH
1020 err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
1021 if (err < 0)
a664b5bc 1022 mgmt_pending_remove(cmd);
9fbcbb45
JH
1023
1024failed:
09fd0de5 1025 hci_dev_unlock(hdev);
9fbcbb45
JH
1026 hci_dev_put(hdev);
1027
1028 return err;
1029}
1030
650f726d 1031static int set_pairable(struct sock *sk, u16 index, void *data, u16 len)
c542a06c 1032{
650f726d 1033 struct mgmt_mode *cp = data;
c542a06c 1034 struct hci_dev *hdev;
c542a06c
JH
1035 int err;
1036
4e51eae9 1037 BT_DBG("request for hci%u", index);
c542a06c 1038
bdce7baf 1039 if (len != sizeof(*cp))
ca69b795
JH
1040 return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE,
1041 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1042
4e51eae9 1043 hdev = hci_dev_get(index);
c542a06c 1044 if (!hdev)
ca69b795
JH
1045 return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE,
1046 MGMT_STATUS_INVALID_PARAMS);
c542a06c 1047
09fd0de5 1048 hci_dev_lock(hdev);
c542a06c
JH
1049
1050 if (cp->val)
a8b2d5c2 1051 set_bit(HCI_PAIRABLE, &hdev->dev_flags);
c542a06c 1052 else
a8b2d5c2 1053 clear_bit(HCI_PAIRABLE, &hdev->dev_flags);
c542a06c 1054
69ab39ea 1055 err = send_settings_rsp(sk, MGMT_OP_SET_PAIRABLE, hdev);
c542a06c
JH
1056 if (err < 0)
1057 goto failed;
1058
beadb2bd 1059 err = new_settings(hdev, sk);
c542a06c
JH
1060
1061failed:
09fd0de5 1062 hci_dev_unlock(hdev);
c542a06c
JH
1063 hci_dev_put(hdev);
1064
1065 return err;
1066}
1067
33ef95ed
JH
1068static int set_link_security(struct sock *sk, u16 index, void *data, u16 len)
1069{
1070 struct mgmt_mode *cp = data;
1071 struct pending_cmd *cmd;
1072 struct hci_dev *hdev;
1073 uint8_t val;
1074 int err;
1075
1076 BT_DBG("request for hci%u", index);
1077
1078 if (len != sizeof(*cp))
1079 return cmd_status(sk, index, MGMT_OP_SET_LINK_SECURITY,
1080 MGMT_STATUS_INVALID_PARAMS);
1081
1082 hdev = hci_dev_get(index);
1083 if (!hdev)
1084 return cmd_status(sk, index, MGMT_OP_SET_LINK_SECURITY,
1085 MGMT_STATUS_INVALID_PARAMS);
1086
1087 hci_dev_lock(hdev);
1088
4b34ee78 1089 if (!hdev_is_powered(hdev)) {
47990ea0
JH
1090 bool changed = false;
1091
1092 if (!!cp->val != test_bit(HCI_LINK_SECURITY,
1093 &hdev->dev_flags)) {
1094 change_bit(HCI_LINK_SECURITY, &hdev->dev_flags);
1095 changed = true;
1096 }
1097
1098 err = send_settings_rsp(sk, MGMT_OP_SET_LINK_SECURITY, hdev);
1099 if (err < 0)
1100 goto failed;
1101
1102 if (changed)
1103 err = new_settings(hdev, sk);
1104
33ef95ed
JH
1105 goto failed;
1106 }
1107
1108 if (mgmt_pending_find(MGMT_OP_SET_LINK_SECURITY, hdev)) {
1109 err = cmd_status(sk, index, MGMT_OP_SET_LINK_SECURITY,
1110 MGMT_STATUS_BUSY);
1111 goto failed;
1112 }
1113
1114 val = !!cp->val;
1115
1116 if (test_bit(HCI_AUTH, &hdev->flags) == val) {
1117 err = send_settings_rsp(sk, MGMT_OP_SET_LINK_SECURITY, hdev);
1118 goto failed;
1119 }
1120
1121 cmd = mgmt_pending_add(sk, MGMT_OP_SET_LINK_SECURITY, hdev, data, len);
1122 if (!cmd) {
1123 err = -ENOMEM;
1124 goto failed;
1125 }
1126
1127 err = hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, sizeof(val), &val);
1128 if (err < 0) {
1129 mgmt_pending_remove(cmd);
1130 goto failed;
1131 }
1132
1133failed:
1134 hci_dev_unlock(hdev);
1135 hci_dev_put(hdev);
1136
1137 return err;
1138}
1139
ed2c4ee3
JH
1140static int set_ssp(struct sock *sk, u16 index, void *data, u16 len)
1141{
1142 struct mgmt_mode *cp = data;
1143 struct pending_cmd *cmd;
1144 struct hci_dev *hdev;
1145 uint8_t val;
1146 int err;
1147
1148 BT_DBG("request for hci%u", index);
1149
1150 if (len != sizeof(*cp))
1151 return cmd_status(sk, index, MGMT_OP_SET_SSP,
1152 MGMT_STATUS_INVALID_PARAMS);
1153
1154 hdev = hci_dev_get(index);
1155 if (!hdev)
1156 return cmd_status(sk, index, MGMT_OP_SET_SSP,
1157 MGMT_STATUS_INVALID_PARAMS);
1158
1159 hci_dev_lock(hdev);
1160
6c8f12c1
JH
1161 if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) {
1162 err = cmd_status(sk, index, MGMT_OP_SET_SSP,
1163 MGMT_STATUS_NOT_SUPPORTED);
1164 goto failed;
1165 }
1166
c0ecddc2
JH
1167 val = !!cp->val;
1168
4b34ee78 1169 if (!hdev_is_powered(hdev)) {
c0ecddc2
JH
1170 bool changed = false;
1171
1172 if (val != test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
1173 change_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
1174 changed = true;
1175 }
1176
1177 err = send_settings_rsp(sk, MGMT_OP_SET_SSP, hdev);
1178 if (err < 0)
1179 goto failed;
1180
1181 if (changed)
1182 err = new_settings(hdev, sk);
1183
ed2c4ee3
JH
1184 goto failed;
1185 }
1186
1187 if (mgmt_pending_find(MGMT_OP_SET_SSP, hdev)) {
1188 err = cmd_status(sk, index, MGMT_OP_SET_SSP, MGMT_STATUS_BUSY);
1189 goto failed;
1190 }
1191
ed2c4ee3
JH
1192 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) == val) {
1193 err = send_settings_rsp(sk, MGMT_OP_SET_SSP, hdev);
1194 goto failed;
1195 }
1196
1197 cmd = mgmt_pending_add(sk, MGMT_OP_SET_SSP, hdev, data, len);
1198 if (!cmd) {
1199 err = -ENOMEM;
1200 goto failed;
1201 }
1202
1203 err = hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(val), &val);
1204 if (err < 0) {
1205 mgmt_pending_remove(cmd);
1206 goto failed;
1207 }
1208
1209failed:
1210 hci_dev_unlock(hdev);
1211 hci_dev_put(hdev);
1212
1213 return err;
1214}
1215
6d80dfd0
JH
1216static int set_hs(struct sock *sk, u16 index, void *data, u16 len)
1217{
1218 struct mgmt_mode *cp = data;
1219 struct hci_dev *hdev;
1220 int err;
1221
1222 BT_DBG("request for hci%u", index);
1223
1224 if (len != sizeof(*cp))
1225 return cmd_status(sk, index, MGMT_OP_SET_HS,
1226 MGMT_STATUS_INVALID_PARAMS);
1227
1228 hdev = hci_dev_get(index);
1229 if (!hdev)
1230 return cmd_status(sk, index, MGMT_OP_SET_HS,
1231 MGMT_STATUS_INVALID_PARAMS);
1232
1233 if (!enable_hs) {
1234 err = cmd_status(sk, index, MGMT_OP_SET_HS,
1235 MGMT_STATUS_NOT_SUPPORTED);
1236 goto failed;
1237 }
1238
1239 if (cp->val)
1240 set_bit(HCI_HS_ENABLED, &hdev->dev_flags);
1241 else
1242 clear_bit(HCI_HS_ENABLED, &hdev->dev_flags);
1243
1244 err = send_settings_rsp(sk, MGMT_OP_SET_HS, hdev);
1245
1246failed:
1247 hci_dev_put(hdev);
1248 return err;
1249}
1250
06199cf8
JH
1251static int set_le(struct sock *sk, u16 index, void *data, u16 len)
1252{
1253 struct mgmt_mode *cp = data;
1254 struct hci_cp_write_le_host_supported hci_cp;
1255 struct pending_cmd *cmd;
1256 struct hci_dev *hdev;
1257 int err;
1258 u8 val;
1259
1260 BT_DBG("request for hci%u", index);
1261
1262 if (len != sizeof(*cp))
1263 return cmd_status(sk, index, MGMT_OP_SET_LE,
1264 MGMT_STATUS_INVALID_PARAMS);
1265
1266 hdev = hci_dev_get(index);
1267 if (!hdev)
1268 return cmd_status(sk, index, MGMT_OP_SET_LE,
1269 MGMT_STATUS_INVALID_PARAMS);
1270
1271 if (!enable_le || !(hdev->features[4] & LMP_LE)) {
1272 err = cmd_status(sk, index, MGMT_OP_SET_LE,
1273 MGMT_STATUS_NOT_SUPPORTED);
1274 goto failed;
1275 }
1276
1277 val = !!cp->val;
1278
1279 if (!hdev_is_powered(hdev)) {
1280 bool changed = false;
1281
1282 if (val != test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
1283 change_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1284 changed = true;
1285 }
1286
1287 err = send_settings_rsp(sk, MGMT_OP_SET_LE, hdev);
1288 if (err < 0)
1289 goto failed;
1290
1291 if (changed)
1292 err = new_settings(hdev, sk);
1293
1294 goto failed;
1295 }
1296
1297 if (mgmt_pending_find(MGMT_OP_SET_LE, hdev)) {
1298 err = cmd_status(sk, index, MGMT_OP_SET_LE, MGMT_STATUS_BUSY);
1299 goto failed;
1300 }
1301
1302 cmd = mgmt_pending_add(sk, MGMT_OP_SET_LE, hdev, data, len);
1303 if (!cmd) {
1304 err = -ENOMEM;
1305 goto failed;
1306 }
1307
1308 memset(&hci_cp, 0, sizeof(hci_cp));
1309
1310 if (val) {
1311 hci_cp.le = val;
1312 hci_cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
1313 }
1314
1315 err = hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED,
1316 sizeof(hci_cp), &hci_cp);
1317 if (err < 0) {
1318 mgmt_pending_remove(cmd);
1319 goto failed;
1320 }
1321
1322failed:
1323 hci_dev_put(hdev);
1324 return err;
1325}
1326
650f726d 1327static int add_uuid(struct sock *sk, u16 index, void *data, u16 len)
2aeb9a1a 1328{
650f726d 1329 struct mgmt_cp_add_uuid *cp = data;
2aeb9a1a
JH
1330 struct hci_dev *hdev;
1331 struct bt_uuid *uuid;
2aeb9a1a
JH
1332 int err;
1333
4e51eae9 1334 BT_DBG("request for hci%u", index);
2aeb9a1a 1335
bdce7baf 1336 if (len != sizeof(*cp))
ca69b795
JH
1337 return cmd_status(sk, index, MGMT_OP_ADD_UUID,
1338 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1339
4e51eae9 1340 hdev = hci_dev_get(index);
2aeb9a1a 1341 if (!hdev)
ca69b795
JH
1342 return cmd_status(sk, index, MGMT_OP_ADD_UUID,
1343 MGMT_STATUS_INVALID_PARAMS);
2aeb9a1a 1344
09fd0de5 1345 hci_dev_lock(hdev);
2aeb9a1a
JH
1346
1347 uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC);
1348 if (!uuid) {
1349 err = -ENOMEM;
1350 goto failed;
1351 }
1352
1353 memcpy(uuid->uuid, cp->uuid, 16);
1aff6f09 1354 uuid->svc_hint = cp->svc_hint;
2aeb9a1a
JH
1355
1356 list_add(&uuid->list, &hdev->uuids);
1357
1aff6f09
JH
1358 err = update_class(hdev);
1359 if (err < 0)
1360 goto failed;
1361
80a1e1db
JH
1362 err = update_eir(hdev);
1363 if (err < 0)
1364 goto failed;
1365
9997a533 1366 err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, 0, hdev->dev_class, 3);
2aeb9a1a
JH
1367
1368failed:
09fd0de5 1369 hci_dev_unlock(hdev);
2aeb9a1a
JH
1370 hci_dev_put(hdev);
1371
1372 return err;
1373}
1374
650f726d 1375static int remove_uuid(struct sock *sk, u16 index, void *data, u16 len)
2aeb9a1a 1376{
650f726d 1377 struct mgmt_cp_remove_uuid *cp = data;
2aeb9a1a 1378 struct list_head *p, *n;
2aeb9a1a
JH
1379 struct hci_dev *hdev;
1380 u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2aeb9a1a
JH
1381 int err, found;
1382
4e51eae9 1383 BT_DBG("request for hci%u", index);
2aeb9a1a 1384
bdce7baf 1385 if (len != sizeof(*cp))
ca69b795
JH
1386 return cmd_status(sk, index, MGMT_OP_REMOVE_UUID,
1387 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1388
4e51eae9 1389 hdev = hci_dev_get(index);
2aeb9a1a 1390 if (!hdev)
ca69b795
JH
1391 return cmd_status(sk, index, MGMT_OP_REMOVE_UUID,
1392 MGMT_STATUS_INVALID_PARAMS);
2aeb9a1a 1393
09fd0de5 1394 hci_dev_lock(hdev);
2aeb9a1a
JH
1395
1396 if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) {
1397 err = hci_uuids_clear(hdev);
4004b6d9
JH
1398
1399 if (hdev_is_powered(hdev) &&
1400 !test_and_set_bit(HCI_SERVICE_CACHE, &hdev->dev_flags))
1401 schedule_delayed_work(&hdev->service_cache,
1402 msecs_to_jiffies(SERVICE_CACHE_TIMEOUT));
1403
2aeb9a1a
JH
1404 goto unlock;
1405 }
1406
1407 found = 0;
1408
1409 list_for_each_safe(p, n, &hdev->uuids) {
1410 struct bt_uuid *match = list_entry(p, struct bt_uuid, list);
1411
1412 if (memcmp(match->uuid, cp->uuid, 16) != 0)
1413 continue;
1414
1415 list_del(&match->list);
1416 found++;
1417 }
1418
1419 if (found == 0) {
ca69b795
JH
1420 err = cmd_status(sk, index, MGMT_OP_REMOVE_UUID,
1421 MGMT_STATUS_INVALID_PARAMS);
2aeb9a1a
JH
1422 goto unlock;
1423 }
1424
1aff6f09
JH
1425 err = update_class(hdev);
1426 if (err < 0)
1427 goto unlock;
1428
80a1e1db
JH
1429 err = update_eir(hdev);
1430 if (err < 0)
1431 goto unlock;
1432
9997a533
JH
1433 err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, 0,
1434 hdev->dev_class, 3);
2aeb9a1a
JH
1435
1436unlock:
09fd0de5 1437 hci_dev_unlock(hdev);
2aeb9a1a
JH
1438 hci_dev_put(hdev);
1439
1440 return err;
1441}
1442
650f726d 1443static int set_dev_class(struct sock *sk, u16 index, void *data, u16 len)
1aff6f09
JH
1444{
1445 struct hci_dev *hdev;
650f726d 1446 struct mgmt_cp_set_dev_class *cp = data;
1aff6f09
JH
1447 int err;
1448
4e51eae9 1449 BT_DBG("request for hci%u", index);
1aff6f09 1450
bdce7baf 1451 if (len != sizeof(*cp))
ca69b795
JH
1452 return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS,
1453 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1454
4e51eae9 1455 hdev = hci_dev_get(index);
1aff6f09 1456 if (!hdev)
ca69b795
JH
1457 return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS,
1458 MGMT_STATUS_INVALID_PARAMS);
1aff6f09 1459
09fd0de5 1460 hci_dev_lock(hdev);
1aff6f09 1461
932f5ff5
JH
1462 hdev->major_class = cp->major;
1463 hdev->minor_class = cp->minor;
1464
b5235a65 1465 if (!hdev_is_powered(hdev)) {
932f5ff5
JH
1466 err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, 0,
1467 hdev->dev_class, 3);
b5235a65
JH
1468 goto unlock;
1469 }
1470
a8b2d5c2 1471 if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->dev_flags)) {
7d78525d
JH
1472 hci_dev_unlock(hdev);
1473 cancel_delayed_work_sync(&hdev->service_cache);
1474 hci_dev_lock(hdev);
14c0b608 1475 update_eir(hdev);
7d78525d 1476 }
14c0b608 1477
1aff6f09
JH
1478 err = update_class(hdev);
1479
1480 if (err == 0)
aee9b218 1481 err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, 0,
8ec37034 1482 hdev->dev_class, 3);
1aff6f09 1483
b5235a65 1484unlock:
09fd0de5 1485 hci_dev_unlock(hdev);
1aff6f09
JH
1486 hci_dev_put(hdev);
1487
1488 return err;
1489}
1490
650f726d 1491static int load_link_keys(struct sock *sk, u16 index, void *data, u16 len)
55ed8ca1
JH
1492{
1493 struct hci_dev *hdev;
650f726d 1494 struct mgmt_cp_load_link_keys *cp = data;
4e51eae9 1495 u16 key_count, expected_len;
a492cd52 1496 int i;
55ed8ca1 1497
bdce7baf 1498 if (len < sizeof(*cp))
ca69b795
JH
1499 return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS,
1500 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1501
55ed8ca1
JH
1502 key_count = get_unaligned_le16(&cp->key_count);
1503
86742e1e
JH
1504 expected_len = sizeof(*cp) + key_count *
1505 sizeof(struct mgmt_link_key_info);
a492cd52 1506 if (expected_len != len) {
86742e1e 1507 BT_ERR("load_link_keys: expected %u bytes, got %u bytes",
a492cd52 1508 len, expected_len);
ca69b795
JH
1509 return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS,
1510 MGMT_STATUS_INVALID_PARAMS);
55ed8ca1
JH
1511 }
1512
4e51eae9 1513 hdev = hci_dev_get(index);
55ed8ca1 1514 if (!hdev)
ca69b795
JH
1515 return cmd_status(sk, index, MGMT_OP_LOAD_LINK_KEYS,
1516 MGMT_STATUS_INVALID_PARAMS);
55ed8ca1 1517
4e51eae9 1518 BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys,
55ed8ca1
JH
1519 key_count);
1520
09fd0de5 1521 hci_dev_lock(hdev);
55ed8ca1
JH
1522
1523 hci_link_keys_clear(hdev);
1524
a8b2d5c2 1525 set_bit(HCI_LINK_KEYS, &hdev->dev_flags);
55ed8ca1
JH
1526
1527 if (cp->debug_keys)
a8b2d5c2 1528 set_bit(HCI_DEBUG_KEYS, &hdev->dev_flags);
55ed8ca1 1529 else
a8b2d5c2 1530 clear_bit(HCI_DEBUG_KEYS, &hdev->dev_flags);
55ed8ca1 1531
a492cd52 1532 for (i = 0; i < key_count; i++) {
86742e1e 1533 struct mgmt_link_key_info *key = &cp->keys[i];
55ed8ca1 1534
d753fdc4
JH
1535 hci_add_link_key(hdev, NULL, 0, &key->addr.bdaddr, key->val,
1536 key->type, key->pin_len);
55ed8ca1
JH
1537 }
1538
aee9b218 1539 cmd_complete(sk, index, MGMT_OP_LOAD_LINK_KEYS, 0, NULL, 0);
0e5f875a 1540
09fd0de5 1541 hci_dev_unlock(hdev);
55ed8ca1
JH
1542 hci_dev_put(hdev);
1543
a492cd52 1544 return 0;
55ed8ca1
JH
1545}
1546
b1078ad0
JH
1547static int device_unpaired(struct hci_dev *hdev, bdaddr_t *bdaddr,
1548 u8 addr_type, struct sock *skip_sk)
1549{
1550 struct mgmt_ev_device_unpaired ev;
1551
1552 bacpy(&ev.addr.bdaddr, bdaddr);
1553 ev.addr.type = addr_type;
1554
1555 return mgmt_event(MGMT_EV_DEVICE_UNPAIRED, hdev, &ev, sizeof(ev),
1556 skip_sk);
1557}
1558
124f6e35 1559static int unpair_device(struct sock *sk, u16 index, void *data, u16 len)
55ed8ca1
JH
1560{
1561 struct hci_dev *hdev;
124f6e35
JH
1562 struct mgmt_cp_unpair_device *cp = data;
1563 struct mgmt_rp_unpair_device rp;
a8a1d19e
JH
1564 struct hci_cp_disconnect dc;
1565 struct pending_cmd *cmd;
55ed8ca1 1566 struct hci_conn *conn;
55ed8ca1
JH
1567 int err;
1568
bdce7baf 1569 if (len != sizeof(*cp))
124f6e35 1570 return cmd_status(sk, index, MGMT_OP_UNPAIR_DEVICE,
ca69b795 1571 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1572
4e51eae9 1573 hdev = hci_dev_get(index);
55ed8ca1 1574 if (!hdev)
124f6e35 1575 return cmd_status(sk, index, MGMT_OP_UNPAIR_DEVICE,
ca69b795 1576 MGMT_STATUS_INVALID_PARAMS);
55ed8ca1 1577
09fd0de5 1578 hci_dev_lock(hdev);
55ed8ca1 1579
a8a1d19e 1580 memset(&rp, 0, sizeof(rp));
124f6e35
JH
1581 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
1582 rp.addr.type = cp->addr.type;
a8a1d19e 1583
86a8cfc6
JH
1584 if (!hdev_is_powered(hdev)) {
1585 err = cmd_complete(sk, index, MGMT_OP_UNPAIR_DEVICE,
1586 MGMT_STATUS_NOT_POWERED,
1587 &rp, sizeof(rp));
1588 goto unlock;
1589 }
1590
124f6e35
JH
1591 if (cp->addr.type == MGMT_ADDR_BREDR)
1592 err = hci_remove_link_key(hdev, &cp->addr.bdaddr);
1593 else
1594 err = hci_remove_ltk(hdev, &cp->addr.bdaddr);
b0dbfb46 1595
55ed8ca1 1596 if (err < 0) {
86a8cfc6
JH
1597 err = cmd_complete(sk, index, MGMT_OP_UNPAIR_DEVICE,
1598 MGMT_STATUS_NOT_PAIRED,
1599 &rp, sizeof(rp));
55ed8ca1
JH
1600 goto unlock;
1601 }
1602
86a8cfc6
JH
1603 if (cp->disconnect) {
1604 if (cp->addr.type == MGMT_ADDR_BREDR)
1605 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
124f6e35 1606 &cp->addr.bdaddr);
86a8cfc6
JH
1607 else
1608 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK,
124f6e35 1609 &cp->addr.bdaddr);
86a8cfc6
JH
1610 } else {
1611 conn = NULL;
1612 }
124f6e35 1613
a8a1d19e 1614 if (!conn) {
86a8cfc6 1615 err = cmd_complete(sk, index, MGMT_OP_UNPAIR_DEVICE, 0,
aee9b218 1616 &rp, sizeof(rp));
b1078ad0 1617 device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, sk);
a8a1d19e
JH
1618 goto unlock;
1619 }
55ed8ca1 1620
124f6e35
JH
1621 cmd = mgmt_pending_add(sk, MGMT_OP_UNPAIR_DEVICE, hdev, cp,
1622 sizeof(*cp));
a8a1d19e
JH
1623 if (!cmd) {
1624 err = -ENOMEM;
1625 goto unlock;
55ed8ca1
JH
1626 }
1627
a8a1d19e
JH
1628 put_unaligned_le16(conn->handle, &dc.handle);
1629 dc.reason = 0x13; /* Remote User Terminated Connection */
1630 err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc);
1631 if (err < 0)
1632 mgmt_pending_remove(cmd);
1633
55ed8ca1 1634unlock:
09fd0de5 1635 hci_dev_unlock(hdev);
55ed8ca1
JH
1636 hci_dev_put(hdev);
1637
1638 return err;
1639}
1640
650f726d 1641static int disconnect(struct sock *sk, u16 index, void *data, u16 len)
8962ee74
JH
1642{
1643 struct hci_dev *hdev;
650f726d 1644 struct mgmt_cp_disconnect *cp = data;
8962ee74 1645 struct hci_cp_disconnect dc;
366a0336 1646 struct pending_cmd *cmd;
8962ee74 1647 struct hci_conn *conn;
8962ee74
JH
1648 int err;
1649
1650 BT_DBG("");
1651
bdce7baf 1652 if (len != sizeof(*cp))
ca69b795
JH
1653 return cmd_status(sk, index, MGMT_OP_DISCONNECT,
1654 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1655
4e51eae9 1656 hdev = hci_dev_get(index);
8962ee74 1657 if (!hdev)
ca69b795
JH
1658 return cmd_status(sk, index, MGMT_OP_DISCONNECT,
1659 MGMT_STATUS_INVALID_PARAMS);
8962ee74 1660
09fd0de5 1661 hci_dev_lock(hdev);
8962ee74
JH
1662
1663 if (!test_bit(HCI_UP, &hdev->flags)) {
ca69b795
JH
1664 err = cmd_status(sk, index, MGMT_OP_DISCONNECT,
1665 MGMT_STATUS_NOT_POWERED);
8962ee74
JH
1666 goto failed;
1667 }
1668
2e58ef3e 1669 if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) {
ca69b795
JH
1670 err = cmd_status(sk, index, MGMT_OP_DISCONNECT,
1671 MGMT_STATUS_BUSY);
8962ee74
JH
1672 goto failed;
1673 }
1674
88c3df13
JH
1675 if (cp->addr.type == MGMT_ADDR_BREDR)
1676 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr);
1677 else
1678 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
365227e5 1679
8962ee74 1680 if (!conn) {
ca69b795
JH
1681 err = cmd_status(sk, index, MGMT_OP_DISCONNECT,
1682 MGMT_STATUS_NOT_CONNECTED);
8962ee74
JH
1683 goto failed;
1684 }
1685
2e58ef3e 1686 cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, hdev, data, len);
366a0336
JH
1687 if (!cmd) {
1688 err = -ENOMEM;
8962ee74 1689 goto failed;
366a0336 1690 }
8962ee74
JH
1691
1692 put_unaligned_le16(conn->handle, &dc.handle);
1693 dc.reason = 0x13; /* Remote User Terminated Connection */
1694
1695 err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc);
1696 if (err < 0)
a664b5bc 1697 mgmt_pending_remove(cmd);
8962ee74
JH
1698
1699failed:
09fd0de5 1700 hci_dev_unlock(hdev);
8962ee74
JH
1701 hci_dev_put(hdev);
1702
1703 return err;
1704}
1705
48264f06 1706static u8 link_to_mgmt(u8 link_type, u8 addr_type)
4c659c39
JH
1707{
1708 switch (link_type) {
1709 case LE_LINK:
48264f06
JH
1710 switch (addr_type) {
1711 case ADDR_LE_DEV_PUBLIC:
1712 return MGMT_ADDR_LE_PUBLIC;
1713 case ADDR_LE_DEV_RANDOM:
1714 return MGMT_ADDR_LE_RANDOM;
1715 default:
1716 return MGMT_ADDR_INVALID;
1717 }
4c659c39
JH
1718 case ACL_LINK:
1719 return MGMT_ADDR_BREDR;
1720 default:
1721 return MGMT_ADDR_INVALID;
1722 }
1723}
1724
8ce6284e 1725static int get_connections(struct sock *sk, u16 index)
2784eb41 1726{
2784eb41
JH
1727 struct mgmt_rp_get_connections *rp;
1728 struct hci_dev *hdev;
8035ded4 1729 struct hci_conn *c;
a38528f1 1730 size_t rp_len;
60fc5fb6
JH
1731 int err;
1732 u16 i;
2784eb41
JH
1733
1734 BT_DBG("");
1735
4e51eae9 1736 hdev = hci_dev_get(index);
2784eb41 1737 if (!hdev)
ca69b795
JH
1738 return cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS,
1739 MGMT_STATUS_INVALID_PARAMS);
2784eb41 1740
09fd0de5 1741 hci_dev_lock(hdev);
2784eb41 1742
5f97c1df
JH
1743 if (!hdev_is_powered(hdev)) {
1744 err = cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS,
1745 MGMT_STATUS_NOT_POWERED);
1746 goto unlock;
1747 }
1748
60fc5fb6 1749 i = 0;
b644ba33
JH
1750 list_for_each_entry(c, &hdev->conn_hash.list, list) {
1751 if (test_bit(HCI_CONN_MGMT_CONNECTED, &c->flags))
60fc5fb6 1752 i++;
2784eb41
JH
1753 }
1754
60fc5fb6 1755 rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info));
a38528f1
JH
1756 rp = kmalloc(rp_len, GFP_ATOMIC);
1757 if (!rp) {
2784eb41
JH
1758 err = -ENOMEM;
1759 goto unlock;
1760 }
1761
2784eb41 1762 i = 0;
4c659c39 1763 list_for_each_entry(c, &hdev->conn_hash.list, list) {
b644ba33
JH
1764 if (!test_bit(HCI_CONN_MGMT_CONNECTED, &c->flags))
1765 continue;
4c659c39 1766 bacpy(&rp->addr[i].bdaddr, &c->dst);
48264f06 1767 rp->addr[i].type = link_to_mgmt(c->type, c->dst_type);
4c659c39
JH
1768 if (rp->addr[i].type == MGMT_ADDR_INVALID)
1769 continue;
1770 i++;
1771 }
1772
60fc5fb6
JH
1773 put_unaligned_le16(i, &rp->conn_count);
1774
4c659c39
JH
1775 /* Recalculate length in case of filtered SCO connections, etc */
1776 rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info));
2784eb41 1777
aee9b218 1778 err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, 0, rp, rp_len);
2784eb41 1779
a38528f1 1780 kfree(rp);
5f97c1df
JH
1781
1782unlock:
09fd0de5 1783 hci_dev_unlock(hdev);
2784eb41
JH
1784 hci_dev_put(hdev);
1785 return err;
1786}
1787
96d97a67
WR
1788static int send_pin_code_neg_reply(struct sock *sk, u16 index,
1789 struct hci_dev *hdev, struct mgmt_cp_pin_code_neg_reply *cp)
1790{
1791 struct pending_cmd *cmd;
1792 int err;
1793
2e58ef3e 1794 cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, hdev, cp,
96d97a67
WR
1795 sizeof(*cp));
1796 if (!cmd)
1797 return -ENOMEM;
1798
d8457698
JH
1799 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
1800 sizeof(cp->addr.bdaddr), &cp->addr.bdaddr);
96d97a67
WR
1801 if (err < 0)
1802 mgmt_pending_remove(cmd);
1803
1804 return err;
1805}
1806
650f726d 1807static int pin_code_reply(struct sock *sk, u16 index, void *data, u16 len)
980e1a53
JH
1808{
1809 struct hci_dev *hdev;
96d97a67 1810 struct hci_conn *conn;
650f726d 1811 struct mgmt_cp_pin_code_reply *cp = data;
980e1a53 1812 struct hci_cp_pin_code_reply reply;
366a0336 1813 struct pending_cmd *cmd;
980e1a53
JH
1814 int err;
1815
1816 BT_DBG("");
1817
bdce7baf 1818 if (len != sizeof(*cp))
ca69b795
JH
1819 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1820 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1821
4e51eae9 1822 hdev = hci_dev_get(index);
980e1a53 1823 if (!hdev)
ca69b795
JH
1824 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1825 MGMT_STATUS_INVALID_PARAMS);
980e1a53 1826
09fd0de5 1827 hci_dev_lock(hdev);
980e1a53 1828
4b34ee78 1829 if (!hdev_is_powered(hdev)) {
ca69b795
JH
1830 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1831 MGMT_STATUS_NOT_POWERED);
980e1a53
JH
1832 goto failed;
1833 }
1834
d8457698 1835 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr);
96d97a67 1836 if (!conn) {
ca69b795
JH
1837 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1838 MGMT_STATUS_NOT_CONNECTED);
96d97a67
WR
1839 goto failed;
1840 }
1841
1842 if (conn->pending_sec_level == BT_SECURITY_HIGH && cp->pin_len != 16) {
d8457698
JH
1843 struct mgmt_cp_pin_code_neg_reply ncp;
1844
1845 memcpy(&ncp.addr, &cp->addr, sizeof(ncp.addr));
96d97a67
WR
1846
1847 BT_ERR("PIN code is not 16 bytes long");
1848
1849 err = send_pin_code_neg_reply(sk, index, hdev, &ncp);
1850 if (err >= 0)
1851 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
ca69b795 1852 MGMT_STATUS_INVALID_PARAMS);
96d97a67
WR
1853
1854 goto failed;
1855 }
1856
650f726d
VCG
1857 cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, hdev, data,
1858 len);
366a0336
JH
1859 if (!cmd) {
1860 err = -ENOMEM;
980e1a53 1861 goto failed;
366a0336 1862 }
980e1a53 1863
d8457698 1864 bacpy(&reply.bdaddr, &cp->addr.bdaddr);
980e1a53 1865 reply.pin_len = cp->pin_len;
24718ca5 1866 memcpy(reply.pin_code, cp->pin_code, sizeof(reply.pin_code));
980e1a53
JH
1867
1868 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_REPLY, sizeof(reply), &reply);
1869 if (err < 0)
a664b5bc 1870 mgmt_pending_remove(cmd);
980e1a53
JH
1871
1872failed:
09fd0de5 1873 hci_dev_unlock(hdev);
980e1a53
JH
1874 hci_dev_put(hdev);
1875
1876 return err;
1877}
1878
650f726d 1879static int pin_code_neg_reply(struct sock *sk, u16 index, void *data, u16 len)
980e1a53
JH
1880{
1881 struct hci_dev *hdev;
650f726d 1882 struct mgmt_cp_pin_code_neg_reply *cp = data;
980e1a53
JH
1883 int err;
1884
1885 BT_DBG("");
1886
bdce7baf
SJ
1887 if (len != sizeof(*cp))
1888 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
ca69b795 1889 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1890
4e51eae9 1891 hdev = hci_dev_get(index);
980e1a53 1892 if (!hdev)
4e51eae9 1893 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
ca69b795 1894 MGMT_STATUS_INVALID_PARAMS);
980e1a53 1895
09fd0de5 1896 hci_dev_lock(hdev);
980e1a53 1897
4b34ee78 1898 if (!hdev_is_powered(hdev)) {
4e51eae9 1899 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
ca69b795 1900 MGMT_STATUS_NOT_POWERED);
980e1a53
JH
1901 goto failed;
1902 }
1903
96d97a67 1904 err = send_pin_code_neg_reply(sk, index, hdev, cp);
980e1a53
JH
1905
1906failed:
09fd0de5 1907 hci_dev_unlock(hdev);
980e1a53
JH
1908 hci_dev_put(hdev);
1909
1910 return err;
1911}
1912
650f726d 1913static int set_io_capability(struct sock *sk, u16 index, void *data, u16 len)
17fa4b9d
JH
1914{
1915 struct hci_dev *hdev;
650f726d 1916 struct mgmt_cp_set_io_capability *cp = data;
17fa4b9d
JH
1917
1918 BT_DBG("");
1919
bdce7baf 1920 if (len != sizeof(*cp))
ca69b795
JH
1921 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY,
1922 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1923
4e51eae9 1924 hdev = hci_dev_get(index);
17fa4b9d 1925 if (!hdev)
ca69b795
JH
1926 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY,
1927 MGMT_STATUS_INVALID_PARAMS);
17fa4b9d 1928
09fd0de5 1929 hci_dev_lock(hdev);
17fa4b9d
JH
1930
1931 hdev->io_capability = cp->io_capability;
1932
1933 BT_DBG("%s IO capability set to 0x%02x", hdev->name,
b8534e0f 1934 hdev->io_capability);
17fa4b9d 1935
09fd0de5 1936 hci_dev_unlock(hdev);
17fa4b9d
JH
1937 hci_dev_put(hdev);
1938
aee9b218 1939 return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, 0, NULL, 0);
17fa4b9d
JH
1940}
1941
e9a416b5
JH
1942static inline struct pending_cmd *find_pairing(struct hci_conn *conn)
1943{
1944 struct hci_dev *hdev = conn->hdev;
8035ded4 1945 struct pending_cmd *cmd;
e9a416b5 1946
2e58ef3e 1947 list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
e9a416b5
JH
1948 if (cmd->opcode != MGMT_OP_PAIR_DEVICE)
1949 continue;
1950
e9a416b5
JH
1951 if (cmd->user_data != conn)
1952 continue;
1953
1954 return cmd;
1955 }
1956
1957 return NULL;
1958}
1959
1960static void pairing_complete(struct pending_cmd *cmd, u8 status)
1961{
1962 struct mgmt_rp_pair_device rp;
1963 struct hci_conn *conn = cmd->user_data;
1964
ba4e564f
JH
1965 bacpy(&rp.addr.bdaddr, &conn->dst);
1966 rp.addr.type = link_to_mgmt(conn->type, conn->dst_type);
e9a416b5 1967
aee9b218
JH
1968 cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, status,
1969 &rp, sizeof(rp));
e9a416b5
JH
1970
1971 /* So we don't get further callbacks for this connection */
1972 conn->connect_cfm_cb = NULL;
1973 conn->security_cfm_cb = NULL;
1974 conn->disconn_cfm_cb = NULL;
1975
1976 hci_conn_put(conn);
1977
a664b5bc 1978 mgmt_pending_remove(cmd);
e9a416b5
JH
1979}
1980
1981static void pairing_complete_cb(struct hci_conn *conn, u8 status)
1982{
1983 struct pending_cmd *cmd;
1984
1985 BT_DBG("status %u", status);
1986
1987 cmd = find_pairing(conn);
56e5cb86 1988 if (!cmd)
e9a416b5 1989 BT_DBG("Unable to find a pending command");
56e5cb86 1990 else
e211326c 1991 pairing_complete(cmd, mgmt_status(status));
e9a416b5
JH
1992}
1993
650f726d 1994static int pair_device(struct sock *sk, u16 index, void *data, u16 len)
e9a416b5
JH
1995{
1996 struct hci_dev *hdev;
650f726d 1997 struct mgmt_cp_pair_device *cp = data;
1425acb7 1998 struct mgmt_rp_pair_device rp;
e9a416b5
JH
1999 struct pending_cmd *cmd;
2000 u8 sec_level, auth_type;
2001 struct hci_conn *conn;
e9a416b5
JH
2002 int err;
2003
2004 BT_DBG("");
2005
bdce7baf 2006 if (len != sizeof(*cp))
ca69b795
JH
2007 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE,
2008 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 2009
4e51eae9 2010 hdev = hci_dev_get(index);
e9a416b5 2011 if (!hdev)
ca69b795
JH
2012 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE,
2013 MGMT_STATUS_INVALID_PARAMS);
e9a416b5 2014
09fd0de5 2015 hci_dev_lock(hdev);
e9a416b5 2016
5f97c1df
JH
2017 if (!hdev_is_powered(hdev)) {
2018 err = cmd_status(sk, index, MGMT_OP_PAIR_DEVICE,
2019 MGMT_STATUS_NOT_POWERED);
2020 goto unlock;
2021 }
2022
c908df36
VCG
2023 sec_level = BT_SECURITY_MEDIUM;
2024 if (cp->io_cap == 0x03)
e9a416b5 2025 auth_type = HCI_AT_DEDICATED_BONDING;
c908df36 2026 else
e9a416b5 2027 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
e9a416b5 2028
ba4e564f
JH
2029 if (cp->addr.type == MGMT_ADDR_BREDR)
2030 conn = hci_connect(hdev, ACL_LINK, &cp->addr.bdaddr, sec_level,
7a512d01
VCG
2031 auth_type);
2032 else
ba4e564f 2033 conn = hci_connect(hdev, LE_LINK, &cp->addr.bdaddr, sec_level,
7a512d01
VCG
2034 auth_type);
2035
1425acb7
JH
2036 memset(&rp, 0, sizeof(rp));
2037 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
2038 rp.addr.type = cp->addr.type;
2039
30e76272 2040 if (IS_ERR(conn)) {
e211326c
JH
2041 err = cmd_complete(sk, index, MGMT_OP_PAIR_DEVICE,
2042 MGMT_STATUS_CONNECT_FAILED,
2043 &rp, sizeof(rp));
e9a416b5
JH
2044 goto unlock;
2045 }
2046
2047 if (conn->connect_cfm_cb) {
2048 hci_conn_put(conn);
e211326c
JH
2049 err = cmd_complete(sk, index, MGMT_OP_PAIR_DEVICE,
2050 MGMT_STATUS_BUSY, &rp, sizeof(rp));
e9a416b5
JH
2051 goto unlock;
2052 }
2053
2e58ef3e 2054 cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, hdev, data, len);
e9a416b5
JH
2055 if (!cmd) {
2056 err = -ENOMEM;
2057 hci_conn_put(conn);
2058 goto unlock;
2059 }
2060
7a512d01 2061 /* For LE, just connecting isn't a proof that the pairing finished */
ba4e564f 2062 if (cp->addr.type == MGMT_ADDR_BREDR)
7a512d01
VCG
2063 conn->connect_cfm_cb = pairing_complete_cb;
2064
e9a416b5
JH
2065 conn->security_cfm_cb = pairing_complete_cb;
2066 conn->disconn_cfm_cb = pairing_complete_cb;
2067 conn->io_capability = cp->io_cap;
2068 cmd->user_data = conn;
2069
2070 if (conn->state == BT_CONNECTED &&
2071 hci_conn_security(conn, sec_level, auth_type))
2072 pairing_complete(cmd, 0);
2073
2074 err = 0;
2075
2076unlock:
09fd0de5 2077 hci_dev_unlock(hdev);
e9a416b5
JH
2078 hci_dev_put(hdev);
2079
2080 return err;
2081}
2082
28424707
JH
2083static int cancel_pair_device(struct sock *sk, u16 index,
2084 unsigned char *data, u16 len)
2085{
2086 struct mgmt_addr_info *addr = (void *) data;
2087 struct hci_dev *hdev;
2088 struct pending_cmd *cmd;
2089 struct hci_conn *conn;
2090 int err;
2091
2092 BT_DBG("");
2093
2094 if (len != sizeof(*addr))
2095 return cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
2096 MGMT_STATUS_INVALID_PARAMS);
2097
2098 hdev = hci_dev_get(index);
2099 if (!hdev)
2100 return cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
2101 MGMT_STATUS_INVALID_PARAMS);
2102
2103 hci_dev_lock(hdev);
2104
5f97c1df
JH
2105 if (!hdev_is_powered(hdev)) {
2106 err = cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
2107 MGMT_STATUS_NOT_POWERED);
2108 goto unlock;
2109 }
2110
28424707
JH
2111 cmd = mgmt_pending_find(MGMT_OP_PAIR_DEVICE, hdev);
2112 if (!cmd) {
2113 err = cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
2114 MGMT_STATUS_INVALID_PARAMS);
2115 goto unlock;
2116 }
2117
2118 conn = cmd->user_data;
2119
2120 if (bacmp(&addr->bdaddr, &conn->dst) != 0) {
2121 err = cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
2122 MGMT_STATUS_INVALID_PARAMS);
2123 goto unlock;
2124 }
2125
2126 pairing_complete(cmd, MGMT_STATUS_CANCELLED);
2127
aee9b218 2128 err = cmd_complete(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE, 0, addr,
28424707
JH
2129 sizeof(*addr));
2130unlock:
2131 hci_dev_unlock(hdev);
2132 hci_dev_put(hdev);
2133
2134 return err;
2135}
2136
0df4c185 2137static int user_pairing_resp(struct sock *sk, u16 index, bdaddr_t *bdaddr,
272d90df
JH
2138 u8 type, u16 mgmt_op, u16 hci_op,
2139 __le32 passkey)
a5c29683 2140{
a5c29683
JH
2141 struct pending_cmd *cmd;
2142 struct hci_dev *hdev;
0df4c185 2143 struct hci_conn *conn;
a5c29683
JH
2144 int err;
2145
4e51eae9 2146 hdev = hci_dev_get(index);
a5c29683 2147 if (!hdev)
ca69b795
JH
2148 return cmd_status(sk, index, mgmt_op,
2149 MGMT_STATUS_INVALID_PARAMS);
a5c29683 2150
09fd0de5 2151 hci_dev_lock(hdev);
08ba5382 2152
4b34ee78 2153 if (!hdev_is_powered(hdev)) {
0df4c185
BG
2154 err = cmd_status(sk, index, mgmt_op, MGMT_STATUS_NOT_POWERED);
2155 goto done;
a5c29683
JH
2156 }
2157
272d90df
JH
2158 if (type == MGMT_ADDR_BREDR)
2159 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, bdaddr);
2160 else
47c15e2b 2161 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr);
272d90df
JH
2162
2163 if (!conn) {
2164 err = cmd_status(sk, index, mgmt_op,
47c15e2b 2165 MGMT_STATUS_NOT_CONNECTED);
272d90df
JH
2166 goto done;
2167 }
47c15e2b 2168
272d90df 2169 if (type == MGMT_ADDR_LE_PUBLIC || type == MGMT_ADDR_LE_RANDOM) {
47c15e2b 2170 /* Continue with pairing via SMP */
5fe57d9e
BG
2171 err = smp_user_confirm_reply(conn, mgmt_op, passkey);
2172
2173 if (!err)
2174 err = cmd_status(sk, index, mgmt_op,
2175 MGMT_STATUS_SUCCESS);
2176 else
2177 err = cmd_status(sk, index, mgmt_op,
2178 MGMT_STATUS_FAILED);
47c15e2b 2179
47c15e2b
BG
2180 goto done;
2181 }
2182
0df4c185 2183 cmd = mgmt_pending_add(sk, mgmt_op, hdev, bdaddr, sizeof(*bdaddr));
a5c29683
JH
2184 if (!cmd) {
2185 err = -ENOMEM;
0df4c185 2186 goto done;
a5c29683
JH
2187 }
2188
0df4c185 2189 /* Continue with pairing via HCI */
604086b7
BG
2190 if (hci_op == HCI_OP_USER_PASSKEY_REPLY) {
2191 struct hci_cp_user_passkey_reply cp;
2192
2193 bacpy(&cp.bdaddr, bdaddr);
2194 cp.passkey = passkey;
2195 err = hci_send_cmd(hdev, hci_op, sizeof(cp), &cp);
2196 } else
2197 err = hci_send_cmd(hdev, hci_op, sizeof(*bdaddr), bdaddr);
2198
a664b5bc
JH
2199 if (err < 0)
2200 mgmt_pending_remove(cmd);
a5c29683 2201
0df4c185 2202done:
09fd0de5 2203 hci_dev_unlock(hdev);
a5c29683
JH
2204 hci_dev_put(hdev);
2205
2206 return err;
2207}
2208
0df4c185
BG
2209static int user_confirm_reply(struct sock *sk, u16 index, void *data, u16 len)
2210{
650f726d 2211 struct mgmt_cp_user_confirm_reply *cp = data;
0df4c185
BG
2212
2213 BT_DBG("");
2214
2215 if (len != sizeof(*cp))
2216 return cmd_status(sk, index, MGMT_OP_USER_CONFIRM_REPLY,
2217 MGMT_STATUS_INVALID_PARAMS);
2218
272d90df
JH
2219 return user_pairing_resp(sk, index, &cp->addr.bdaddr, cp->addr.type,
2220 MGMT_OP_USER_CONFIRM_REPLY,
2221 HCI_OP_USER_CONFIRM_REPLY, 0);
0df4c185
BG
2222}
2223
2224static int user_confirm_neg_reply(struct sock *sk, u16 index, void *data,
2225 u16 len)
2226{
c9c2659f 2227 struct mgmt_cp_user_confirm_neg_reply *cp = data;
0df4c185
BG
2228
2229 BT_DBG("");
2230
2231 if (len != sizeof(*cp))
2232 return cmd_status(sk, index, MGMT_OP_USER_CONFIRM_NEG_REPLY,
2233 MGMT_STATUS_INVALID_PARAMS);
2234
272d90df
JH
2235 return user_pairing_resp(sk, index, &cp->addr.bdaddr, cp->addr.type,
2236 MGMT_OP_USER_CONFIRM_NEG_REPLY,
2237 HCI_OP_USER_CONFIRM_NEG_REPLY, 0);
0df4c185
BG
2238}
2239
604086b7
BG
2240static int user_passkey_reply(struct sock *sk, u16 index, void *data, u16 len)
2241{
650f726d 2242 struct mgmt_cp_user_passkey_reply *cp = data;
604086b7
BG
2243
2244 BT_DBG("");
2245
2246 if (len != sizeof(*cp))
2247 return cmd_status(sk, index, MGMT_OP_USER_PASSKEY_REPLY,
2248 EINVAL);
2249
272d90df
JH
2250 return user_pairing_resp(sk, index, &cp->addr.bdaddr, cp->addr.type,
2251 MGMT_OP_USER_PASSKEY_REPLY,
2252 HCI_OP_USER_PASSKEY_REPLY,
2253 cp->passkey);
604086b7
BG
2254}
2255
2256static int user_passkey_neg_reply(struct sock *sk, u16 index, void *data,
2257 u16 len)
2258{
650f726d 2259 struct mgmt_cp_user_passkey_neg_reply *cp = data;
604086b7
BG
2260
2261 BT_DBG("");
2262
2263 if (len != sizeof(*cp))
2264 return cmd_status(sk, index, MGMT_OP_USER_PASSKEY_NEG_REPLY,
2265 EINVAL);
2266
272d90df
JH
2267 return user_pairing_resp(sk, index, &cp->addr.bdaddr, cp->addr.type,
2268 MGMT_OP_USER_PASSKEY_NEG_REPLY,
2269 HCI_OP_USER_PASSKEY_NEG_REPLY, 0);
604086b7
BG
2270}
2271
650f726d 2272static int set_local_name(struct sock *sk, u16 index, void *data,
b312b161
JH
2273 u16 len)
2274{
650f726d 2275 struct mgmt_cp_set_local_name *mgmt_cp = data;
b312b161
JH
2276 struct hci_cp_write_local_name hci_cp;
2277 struct hci_dev *hdev;
2278 struct pending_cmd *cmd;
2279 int err;
2280
2281 BT_DBG("");
2282
2283 if (len != sizeof(*mgmt_cp))
ca69b795
JH
2284 return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME,
2285 MGMT_STATUS_INVALID_PARAMS);
b312b161
JH
2286
2287 hdev = hci_dev_get(index);
2288 if (!hdev)
ca69b795
JH
2289 return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME,
2290 MGMT_STATUS_INVALID_PARAMS);
b312b161 2291
09fd0de5 2292 hci_dev_lock(hdev);
b312b161 2293
28cc7bde
JH
2294 memcpy(hdev->short_name, mgmt_cp->short_name,
2295 sizeof(hdev->short_name));
2296
b5235a65 2297 if (!hdev_is_powered(hdev)) {
28cc7bde
JH
2298 memcpy(hdev->dev_name, mgmt_cp->name, sizeof(hdev->dev_name));
2299
2300 err = cmd_complete(sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0,
2301 data, len);
2302 if (err < 0)
2303 goto failed;
2304
2305 err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, data, len,
2306 sk);
2307
b5235a65
JH
2308 goto failed;
2309 }
2310
28cc7bde 2311 cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, hdev, data, len);
b312b161
JH
2312 if (!cmd) {
2313 err = -ENOMEM;
2314 goto failed;
2315 }
2316
2317 memcpy(hci_cp.name, mgmt_cp->name, sizeof(hci_cp.name));
2318 err = hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(hci_cp),
2319 &hci_cp);
2320 if (err < 0)
2321 mgmt_pending_remove(cmd);
2322
2323failed:
09fd0de5 2324 hci_dev_unlock(hdev);
b312b161
JH
2325 hci_dev_put(hdev);
2326
2327 return err;
2328}
2329
c35938b2
SJ
2330static int read_local_oob_data(struct sock *sk, u16 index)
2331{
2332 struct hci_dev *hdev;
2333 struct pending_cmd *cmd;
2334 int err;
2335
2336 BT_DBG("hci%u", index);
2337
2338 hdev = hci_dev_get(index);
2339 if (!hdev)
2340 return cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
ca69b795 2341 MGMT_STATUS_INVALID_PARAMS);
c35938b2 2342
09fd0de5 2343 hci_dev_lock(hdev);
c35938b2 2344
4b34ee78 2345 if (!hdev_is_powered(hdev)) {
c35938b2 2346 err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
ca69b795 2347 MGMT_STATUS_NOT_POWERED);
c35938b2
SJ
2348 goto unlock;
2349 }
2350
2351 if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) {
2352 err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
ca69b795 2353 MGMT_STATUS_NOT_SUPPORTED);
c35938b2
SJ
2354 goto unlock;
2355 }
2356
2e58ef3e 2357 if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev)) {
ca69b795
JH
2358 err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
2359 MGMT_STATUS_BUSY);
c35938b2
SJ
2360 goto unlock;
2361 }
2362
2e58ef3e 2363 cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, hdev, NULL, 0);
c35938b2
SJ
2364 if (!cmd) {
2365 err = -ENOMEM;
2366 goto unlock;
2367 }
2368
2369 err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
2370 if (err < 0)
2371 mgmt_pending_remove(cmd);
2372
2373unlock:
09fd0de5 2374 hci_dev_unlock(hdev);
c35938b2
SJ
2375 hci_dev_put(hdev);
2376
2377 return err;
2378}
2379
650f726d
VCG
2380static int add_remote_oob_data(struct sock *sk, u16 index, void *data,
2381 u16 len)
2763eda6
SJ
2382{
2383 struct hci_dev *hdev;
650f726d 2384 struct mgmt_cp_add_remote_oob_data *cp = data;
bf1e3541 2385 u8 status;
2763eda6
SJ
2386 int err;
2387
2388 BT_DBG("hci%u ", index);
2389
2390 if (len != sizeof(*cp))
2391 return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
ca69b795 2392 MGMT_STATUS_INVALID_PARAMS);
2763eda6
SJ
2393
2394 hdev = hci_dev_get(index);
2395 if (!hdev)
bf1e3541
JH
2396 return cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
2397 MGMT_STATUS_INVALID_PARAMS,
2398 &cp->addr, sizeof(cp->addr));
2763eda6 2399
09fd0de5 2400 hci_dev_lock(hdev);
2763eda6 2401
5f97c1df
JH
2402 if (!hdev_is_powered(hdev)) {
2403 err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
2404 MGMT_STATUS_NOT_POWERED,
2405 &cp->addr, sizeof(cp->addr));
2406 goto unlock;
2407 }
2408
664ce4cc 2409 err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr, cp->hash,
2763eda6
SJ
2410 cp->randomizer);
2411 if (err < 0)
bf1e3541 2412 status = MGMT_STATUS_FAILED;
2763eda6 2413 else
bf1e3541
JH
2414 status = 0;
2415
2416 err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, status,
2417 &cp->addr, sizeof(cp->addr));
2763eda6 2418
5f97c1df 2419unlock:
09fd0de5 2420 hci_dev_unlock(hdev);
2763eda6
SJ
2421 hci_dev_put(hdev);
2422
2423 return err;
2424}
2425
2426static int remove_remote_oob_data(struct sock *sk, u16 index,
650f726d 2427 void *data, u16 len)
2763eda6
SJ
2428{
2429 struct hci_dev *hdev;
650f726d 2430 struct mgmt_cp_remove_remote_oob_data *cp = data;
bf1e3541 2431 u8 status;
2763eda6
SJ
2432 int err;
2433
2434 BT_DBG("hci%u ", index);
2435
2436 if (len != sizeof(*cp))
2437 return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
ca69b795 2438 MGMT_STATUS_INVALID_PARAMS);
2763eda6
SJ
2439
2440 hdev = hci_dev_get(index);
2441 if (!hdev)
bf1e3541
JH
2442 return cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
2443 MGMT_STATUS_INVALID_PARAMS,
2444 &cp->addr, sizeof(cp->addr));
2763eda6 2445
09fd0de5 2446 hci_dev_lock(hdev);
2763eda6 2447
5f97c1df
JH
2448 if (!hdev_is_powered(hdev)) {
2449 err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
2450 MGMT_STATUS_NOT_POWERED,
2451 &cp->addr, sizeof(cp->addr));
2452 goto unlock;
2453 }
2454
664ce4cc 2455 err = hci_remove_remote_oob_data(hdev, &cp->addr.bdaddr);
2763eda6 2456 if (err < 0)
bf1e3541 2457 status = MGMT_STATUS_INVALID_PARAMS;
2763eda6 2458 else
bf1e3541
JH
2459 status = 0;
2460
2461 err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, status,
2462 &cp->addr, sizeof(cp->addr));
2763eda6 2463
5f97c1df 2464unlock:
09fd0de5 2465 hci_dev_unlock(hdev);
2763eda6
SJ
2466 hci_dev_put(hdev);
2467
2468 return err;
2469}
2470
5e0452c0
AG
2471static int discovery(struct hci_dev *hdev)
2472{
2473 int err;
2474
2475 if (lmp_host_le_capable(hdev)) {
2476 if (lmp_bredr_capable(hdev)) {
2477 err = hci_le_scan(hdev, LE_SCAN_TYPE,
2478 LE_SCAN_INT, LE_SCAN_WIN,
2479 LE_SCAN_TIMEOUT_BREDR_LE);
2480 } else {
2481 hdev->discovery.type = DISCOV_TYPE_LE;
2482 err = hci_le_scan(hdev, LE_SCAN_TYPE,
2483 LE_SCAN_INT, LE_SCAN_WIN,
2484 LE_SCAN_TIMEOUT_LE_ONLY);
2485 }
2486 } else {
2487 hdev->discovery.type = DISCOV_TYPE_BREDR;
2488 err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR);
2489 }
2490
2491 return err;
2492}
2493
2494int mgmt_interleaved_discovery(struct hci_dev *hdev)
2495{
2496 int err;
2497
2498 BT_DBG("%s", hdev->name);
2499
2500 hci_dev_lock(hdev);
2501
2502 err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR_LE);
2503 if (err < 0)
2504 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
2505
2506 hci_dev_unlock(hdev);
2507
2508 return err;
2509}
2510
450dfdaf 2511static int start_discovery(struct sock *sk, u16 index,
650f726d 2512 void *data, u16 len)
14a53664 2513{
650f726d 2514 struct mgmt_cp_start_discovery *cp = data;
14a53664
JH
2515 struct pending_cmd *cmd;
2516 struct hci_dev *hdev;
2517 int err;
2518
2519 BT_DBG("hci%u", index);
2520
450dfdaf
JH
2521 if (len != sizeof(*cp))
2522 return cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
2523 MGMT_STATUS_INVALID_PARAMS);
2524
14a53664
JH
2525 hdev = hci_dev_get(index);
2526 if (!hdev)
ca69b795
JH
2527 return cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
2528 MGMT_STATUS_INVALID_PARAMS);
14a53664 2529
09fd0de5 2530 hci_dev_lock(hdev);
14a53664 2531
4b34ee78 2532 if (!hdev_is_powered(hdev)) {
ca69b795
JH
2533 err = cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
2534 MGMT_STATUS_NOT_POWERED);
bd2d1334
JH
2535 goto failed;
2536 }
2537
ff9ef578
JH
2538 if (hdev->discovery.state != DISCOVERY_STOPPED) {
2539 err = cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
2540 MGMT_STATUS_BUSY);
2541 goto failed;
2542 }
2543
2e58ef3e 2544 cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, hdev, NULL, 0);
14a53664
JH
2545 if (!cmd) {
2546 err = -ENOMEM;
2547 goto failed;
2548 }
2549
4aab14e5
AG
2550 hdev->discovery.type = cp->type;
2551
2552 switch (hdev->discovery.type) {
f39799f5 2553 case DISCOV_TYPE_BREDR:
3fd24153 2554 err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR);
f39799f5
AG
2555 break;
2556
2557 case DISCOV_TYPE_LE:
3fd24153
AG
2558 err = hci_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT,
2559 LE_SCAN_WIN, LE_SCAN_TIMEOUT_LE_ONLY);
f39799f5
AG
2560 break;
2561
5e0452c0
AG
2562 case DISCOV_TYPE_INTERLEAVED:
2563 err = discovery(hdev);
2564 break;
2565
f39799f5 2566 default:
3fd24153 2567 err = -EINVAL;
f39799f5 2568 }
3fd24153 2569
14a53664
JH
2570 if (err < 0)
2571 mgmt_pending_remove(cmd);
ff9ef578
JH
2572 else
2573 hci_discovery_set_state(hdev, DISCOVERY_STARTING);
14a53664
JH
2574
2575failed:
09fd0de5 2576 hci_dev_unlock(hdev);
14a53664
JH
2577 hci_dev_put(hdev);
2578
2579 return err;
2580}
2581
d930650b 2582static int stop_discovery(struct sock *sk, u16 index, void *data, u16 len)
14a53664 2583{
d930650b 2584 struct mgmt_cp_stop_discovery *mgmt_cp = data;
14a53664
JH
2585 struct hci_dev *hdev;
2586 struct pending_cmd *cmd;
30dc78e1
JH
2587 struct hci_cp_remote_name_req_cancel cp;
2588 struct inquiry_entry *e;
14a53664
JH
2589 int err;
2590
2591 BT_DBG("hci%u", index);
2592
d930650b
JH
2593 if (len != sizeof(*mgmt_cp))
2594 return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY,
2595 MGMT_STATUS_INVALID_PARAMS);
2596
14a53664
JH
2597 hdev = hci_dev_get(index);
2598 if (!hdev)
ca69b795
JH
2599 return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY,
2600 MGMT_STATUS_INVALID_PARAMS);
14a53664 2601
09fd0de5 2602 hci_dev_lock(hdev);
14a53664 2603
30dc78e1 2604 if (!hci_discovery_active(hdev)) {
d930650b
JH
2605 err = cmd_complete(sk, index, MGMT_OP_STOP_DISCOVERY,
2606 MGMT_STATUS_REJECTED,
2607 &mgmt_cp->type, sizeof(mgmt_cp->type));
2608 goto unlock;
2609 }
2610
2611 if (hdev->discovery.type != mgmt_cp->type) {
2612 err = cmd_complete(sk, index, MGMT_OP_STOP_DISCOVERY,
2613 MGMT_STATUS_INVALID_PARAMS,
2614 &mgmt_cp->type, sizeof(mgmt_cp->type));
30dc78e1 2615 goto unlock;
ff9ef578
JH
2616 }
2617
2e58ef3e 2618 cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, NULL, 0);
14a53664
JH
2619 if (!cmd) {
2620 err = -ENOMEM;
30dc78e1
JH
2621 goto unlock;
2622 }
2623
343f935b 2624 if (hdev->discovery.state == DISCOVERY_FINDING) {
30dc78e1
JH
2625 err = hci_cancel_inquiry(hdev);
2626 if (err < 0)
2627 mgmt_pending_remove(cmd);
2628 else
2629 hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
2630 goto unlock;
2631 }
2632
2633 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_PENDING);
2634 if (!e) {
2635 mgmt_pending_remove(cmd);
aee9b218 2636 err = cmd_complete(sk, index, MGMT_OP_STOP_DISCOVERY, 0,
d930650b 2637 &mgmt_cp->type, sizeof(mgmt_cp->type));
30dc78e1
JH
2638 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
2639 goto unlock;
14a53664
JH
2640 }
2641
30dc78e1
JH
2642 bacpy(&cp.bdaddr, &e->data.bdaddr);
2643 err = hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ_CANCEL,
2644 sizeof(cp), &cp);
14a53664
JH
2645 if (err < 0)
2646 mgmt_pending_remove(cmd);
ff9ef578
JH
2647 else
2648 hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
14a53664 2649
30dc78e1 2650unlock:
09fd0de5 2651 hci_dev_unlock(hdev);
14a53664
JH
2652 hci_dev_put(hdev);
2653
2654 return err;
2655}
2656
650f726d 2657static int confirm_name(struct sock *sk, u16 index, void *data, u16 len)
561aafbc 2658{
650f726d 2659 struct mgmt_cp_confirm_name *cp = data;
561aafbc
JH
2660 struct inquiry_entry *e;
2661 struct hci_dev *hdev;
2662 int err;
2663
2664 BT_DBG("hci%u", index);
2665
2666 if (len != sizeof(*cp))
2667 return cmd_status(sk, index, MGMT_OP_CONFIRM_NAME,
2668 MGMT_STATUS_INVALID_PARAMS);
2669
2670 hdev = hci_dev_get(index);
2671 if (!hdev)
2672 return cmd_status(sk, index, MGMT_OP_CONFIRM_NAME,
2673 MGMT_STATUS_INVALID_PARAMS);
2674
2675 hci_dev_lock(hdev);
2676
30dc78e1
JH
2677 if (!hci_discovery_active(hdev)) {
2678 err = cmd_status(sk, index, MGMT_OP_CONFIRM_NAME,
2679 MGMT_STATUS_FAILED);
2680 goto failed;
2681 }
2682
a198e7b1 2683 e = hci_inquiry_cache_lookup_unknown(hdev, &cp->addr.bdaddr);
561aafbc 2684 if (!e) {
e5f0e151 2685 err = cmd_status(sk, index, MGMT_OP_CONFIRM_NAME,
561aafbc
JH
2686 MGMT_STATUS_INVALID_PARAMS);
2687 goto failed;
2688 }
2689
2690 if (cp->name_known) {
2691 e->name_state = NAME_KNOWN;
2692 list_del(&e->list);
2693 } else {
2694 e->name_state = NAME_NEEDED;
a3d4e20a 2695 hci_inquiry_cache_update_resolve(hdev, e);
561aafbc
JH
2696 }
2697
2698 err = 0;
2699
2700failed:
2701 hci_dev_unlock(hdev);
2702
2703 return err;
2704}
2705
650f726d 2706static int block_device(struct sock *sk, u16 index, void *data, u16 len)
7fbec224
AJ
2707{
2708 struct hci_dev *hdev;
650f726d 2709 struct mgmt_cp_block_device *cp = data;
f0eeea8b 2710 u8 status;
7fbec224
AJ
2711 int err;
2712
2713 BT_DBG("hci%u", index);
2714
7fbec224
AJ
2715 if (len != sizeof(*cp))
2716 return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
ca69b795 2717 MGMT_STATUS_INVALID_PARAMS);
7fbec224
AJ
2718
2719 hdev = hci_dev_get(index);
2720 if (!hdev)
f0eeea8b
JH
2721 return cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE,
2722 MGMT_STATUS_INVALID_PARAMS,
2723 &cp->addr, sizeof(cp->addr));
7fbec224 2724
09fd0de5 2725 hci_dev_lock(hdev);
5e762444 2726
88c1fe4b 2727 err = hci_blacklist_add(hdev, &cp->addr.bdaddr, cp->addr.type);
7fbec224 2728 if (err < 0)
f0eeea8b 2729 status = MGMT_STATUS_FAILED;
7fbec224 2730 else
f0eeea8b
JH
2731 status = 0;
2732
2733 err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE, status,
2734 &cp->addr, sizeof(cp->addr));
5e762444 2735
09fd0de5 2736 hci_dev_unlock(hdev);
7fbec224
AJ
2737 hci_dev_put(hdev);
2738
2739 return err;
2740}
2741
650f726d 2742static int unblock_device(struct sock *sk, u16 index, void *data, u16 len)
7fbec224
AJ
2743{
2744 struct hci_dev *hdev;
650f726d 2745 struct mgmt_cp_unblock_device *cp = data;
f0eeea8b 2746 u8 status;
7fbec224
AJ
2747 int err;
2748
2749 BT_DBG("hci%u", index);
2750
7fbec224
AJ
2751 if (len != sizeof(*cp))
2752 return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
ca69b795 2753 MGMT_STATUS_INVALID_PARAMS);
7fbec224
AJ
2754
2755 hdev = hci_dev_get(index);
2756 if (!hdev)
f0eeea8b
JH
2757 return cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE,
2758 MGMT_STATUS_INVALID_PARAMS,
2759 &cp->addr, sizeof(cp->addr));
7fbec224 2760
09fd0de5 2761 hci_dev_lock(hdev);
5e762444 2762
88c1fe4b 2763 err = hci_blacklist_del(hdev, &cp->addr.bdaddr, cp->addr.type);
7fbec224 2764 if (err < 0)
f0eeea8b 2765 status = MGMT_STATUS_INVALID_PARAMS;
7fbec224 2766 else
f0eeea8b
JH
2767 status = 0;
2768
2769 err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE, status,
2770 &cp->addr, sizeof(cp->addr));
5e762444 2771
09fd0de5 2772 hci_dev_unlock(hdev);
7fbec224
AJ
2773 hci_dev_put(hdev);
2774
2775 return err;
2776}
2777
f6422ec6 2778static int set_fast_connectable(struct sock *sk, u16 index,
650f726d 2779 void *data, u16 len)
f6422ec6
AJ
2780{
2781 struct hci_dev *hdev;
650f726d 2782 struct mgmt_mode *cp = data;
f6422ec6
AJ
2783 struct hci_cp_write_page_scan_activity acp;
2784 u8 type;
2785 int err;
2786
2787 BT_DBG("hci%u", index);
2788
2789 if (len != sizeof(*cp))
2790 return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2791 MGMT_STATUS_INVALID_PARAMS);
f6422ec6
AJ
2792
2793 hdev = hci_dev_get(index);
2794 if (!hdev)
2795 return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2796 MGMT_STATUS_INVALID_PARAMS);
5400c044
JH
2797 if (!hdev_is_powered(hdev))
2798 return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
2799 MGMT_STATUS_NOT_POWERED);
2800
2801 if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
2802 return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
2803 MGMT_STATUS_REJECTED);
f6422ec6
AJ
2804
2805 hci_dev_lock(hdev);
2806
f7c6869c 2807 if (cp->val) {
f6422ec6
AJ
2808 type = PAGE_SCAN_TYPE_INTERLACED;
2809 acp.interval = 0x0024; /* 22.5 msec page scan interval */
2810 } else {
2811 type = PAGE_SCAN_TYPE_STANDARD; /* default */
2812 acp.interval = 0x0800; /* default 1.28 sec page scan */
2813 }
2814
2815 acp.window = 0x0012; /* default 11.25 msec page scan window */
2816
2817 err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
2818 sizeof(acp), &acp);
2819 if (err < 0) {
2820 err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2821 MGMT_STATUS_FAILED);
f6422ec6
AJ
2822 goto done;
2823 }
2824
2825 err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type);
2826 if (err < 0) {
2827 err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2828 MGMT_STATUS_FAILED);
f6422ec6
AJ
2829 goto done;
2830 }
2831
aee9b218
JH
2832 err = cmd_complete(sk, index, MGMT_OP_SET_FAST_CONNECTABLE, 0,
2833 NULL, 0);
f6422ec6
AJ
2834done:
2835 hci_dev_unlock(hdev);
2836 hci_dev_put(hdev);
2837
2838 return err;
2839}
2840
346af67b
VCG
2841static int load_long_term_keys(struct sock *sk, u16 index,
2842 void *cp_data, u16 len)
2843{
2844 struct hci_dev *hdev;
2845 struct mgmt_cp_load_long_term_keys *cp = cp_data;
2846 u16 key_count, expected_len;
2847 int i;
2848
2849 if (len < sizeof(*cp))
2850 return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS,
2851 EINVAL);
2852
2853 key_count = get_unaligned_le16(&cp->key_count);
2854
2855 expected_len = sizeof(*cp) + key_count *
2856 sizeof(struct mgmt_ltk_info);
2857 if (expected_len != len) {
2858 BT_ERR("load_keys: expected %u bytes, got %u bytes",
2859 len, expected_len);
2860 return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS,
2861 EINVAL);
2862 }
2863
2864 hdev = hci_dev_get(index);
2865 if (!hdev)
2866 return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS,
2867 ENODEV);
2868
2869 BT_DBG("hci%u key_count %u", index, key_count);
2870
2871 hci_dev_lock(hdev);
2872
2873 hci_smp_ltks_clear(hdev);
2874
2875 for (i = 0; i < key_count; i++) {
2876 struct mgmt_ltk_info *key = &cp->keys[i];
2877 u8 type;
2878
2879 if (key->master)
2880 type = HCI_SMP_LTK;
2881 else
2882 type = HCI_SMP_LTK_SLAVE;
2883
2884 hci_add_ltk(hdev, &key->addr.bdaddr, key->addr.type,
2885 type, 0, key->authenticated, key->val,
2886 key->enc_size, key->ediv, key->rand);
2887 }
2888
2889 hci_dev_unlock(hdev);
2890 hci_dev_put(hdev);
2891
2892 return 0;
2893}
2894
0381101f
JH
2895int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
2896{
650f726d
VCG
2897 void *buf;
2898 u8 *cp;
0381101f 2899 struct mgmt_hdr *hdr;
4e51eae9 2900 u16 opcode, index, len;
0381101f
JH
2901 int err;
2902
2903 BT_DBG("got %zu bytes", msglen);
2904
2905 if (msglen < sizeof(*hdr))
2906 return -EINVAL;
2907
e63a15ec 2908 buf = kmalloc(msglen, GFP_KERNEL);
0381101f
JH
2909 if (!buf)
2910 return -ENOMEM;
2911
2912 if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
2913 err = -EFAULT;
2914 goto done;
2915 }
2916
650f726d 2917 hdr = buf;
0381101f 2918 opcode = get_unaligned_le16(&hdr->opcode);
4e51eae9 2919 index = get_unaligned_le16(&hdr->index);
0381101f
JH
2920 len = get_unaligned_le16(&hdr->len);
2921
2922 if (len != msglen - sizeof(*hdr)) {
2923 err = -EINVAL;
2924 goto done;
2925 }
2926
650f726d
VCG
2927 cp = buf + sizeof(*hdr);
2928
0381101f 2929 switch (opcode) {
02d98129
JH
2930 case MGMT_OP_READ_VERSION:
2931 err = read_version(sk);
2932 break;
e70bb2e8
JH
2933 case MGMT_OP_READ_COMMANDS:
2934 err = read_commands(sk);
2935 break;
faba42eb
JH
2936 case MGMT_OP_READ_INDEX_LIST:
2937 err = read_index_list(sk);
2938 break;
f7b64e69 2939 case MGMT_OP_READ_INFO:
4e51eae9 2940 err = read_controller_info(sk, index);
f7b64e69 2941 break;
eec8d2bc 2942 case MGMT_OP_SET_POWERED:
650f726d 2943 err = set_powered(sk, index, cp, len);
eec8d2bc 2944 break;
73f22f62 2945 case MGMT_OP_SET_DISCOVERABLE:
650f726d 2946 err = set_discoverable(sk, index, cp, len);
73f22f62 2947 break;
9fbcbb45 2948 case MGMT_OP_SET_CONNECTABLE:
650f726d 2949 err = set_connectable(sk, index, cp, len);
9fbcbb45 2950 break;
f7c6869c 2951 case MGMT_OP_SET_FAST_CONNECTABLE:
650f726d 2952 err = set_fast_connectable(sk, index, cp, len);
f7c6869c 2953 break;
c542a06c 2954 case MGMT_OP_SET_PAIRABLE:
650f726d 2955 err = set_pairable(sk, index, cp, len);
c542a06c 2956 break;
33ef95ed
JH
2957 case MGMT_OP_SET_LINK_SECURITY:
2958 err = set_link_security(sk, index, cp, len);
2959 break;
ed2c4ee3
JH
2960 case MGMT_OP_SET_SSP:
2961 err = set_ssp(sk, index, cp, len);
2962 break;
6d80dfd0
JH
2963 case MGMT_OP_SET_HS:
2964 err = set_hs(sk, index, cp, len);
2965 break;
06199cf8
JH
2966 case MGMT_OP_SET_LE:
2967 err = set_le(sk, index, cp, len);
2968 break;
2aeb9a1a 2969 case MGMT_OP_ADD_UUID:
650f726d 2970 err = add_uuid(sk, index, cp, len);
2aeb9a1a
JH
2971 break;
2972 case MGMT_OP_REMOVE_UUID:
650f726d 2973 err = remove_uuid(sk, index, cp, len);
2aeb9a1a 2974 break;
1aff6f09 2975 case MGMT_OP_SET_DEV_CLASS:
650f726d 2976 err = set_dev_class(sk, index, cp, len);
1aff6f09 2977 break;
86742e1e 2978 case MGMT_OP_LOAD_LINK_KEYS:
650f726d 2979 err = load_link_keys(sk, index, cp, len);
55ed8ca1 2980 break;
8962ee74 2981 case MGMT_OP_DISCONNECT:
650f726d 2982 err = disconnect(sk, index, cp, len);
8962ee74 2983 break;
2784eb41 2984 case MGMT_OP_GET_CONNECTIONS:
8ce6284e 2985 err = get_connections(sk, index);
2784eb41 2986 break;
980e1a53 2987 case MGMT_OP_PIN_CODE_REPLY:
650f726d 2988 err = pin_code_reply(sk, index, cp, len);
980e1a53
JH
2989 break;
2990 case MGMT_OP_PIN_CODE_NEG_REPLY:
650f726d 2991 err = pin_code_neg_reply(sk, index, cp, len);
980e1a53 2992 break;
17fa4b9d 2993 case MGMT_OP_SET_IO_CAPABILITY:
650f726d 2994 err = set_io_capability(sk, index, cp, len);
17fa4b9d 2995 break;
e9a416b5 2996 case MGMT_OP_PAIR_DEVICE:
650f726d 2997 err = pair_device(sk, index, cp, len);
e9a416b5 2998 break;
28424707
JH
2999 case MGMT_OP_CANCEL_PAIR_DEVICE:
3000 err = cancel_pair_device(sk, index, buf + sizeof(*hdr), len);
3001 break;
124f6e35
JH
3002 case MGMT_OP_UNPAIR_DEVICE:
3003 err = unpair_device(sk, index, cp, len);
3004 break;
a5c29683 3005 case MGMT_OP_USER_CONFIRM_REPLY:
650f726d 3006 err = user_confirm_reply(sk, index, cp, len);
a5c29683
JH
3007 break;
3008 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
650f726d 3009 err = user_confirm_neg_reply(sk, index, cp, len);
a5c29683 3010 break;
604086b7 3011 case MGMT_OP_USER_PASSKEY_REPLY:
650f726d 3012 err = user_passkey_reply(sk, index, cp, len);
604086b7
BG
3013 break;
3014 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
650f726d 3015 err = user_passkey_neg_reply(sk, index, cp, len);
a5c29683 3016 break;
b312b161 3017 case MGMT_OP_SET_LOCAL_NAME:
650f726d 3018 err = set_local_name(sk, index, cp, len);
b312b161 3019 break;
c35938b2
SJ
3020 case MGMT_OP_READ_LOCAL_OOB_DATA:
3021 err = read_local_oob_data(sk, index);
3022 break;
2763eda6 3023 case MGMT_OP_ADD_REMOTE_OOB_DATA:
650f726d 3024 err = add_remote_oob_data(sk, index, cp, len);
2763eda6
SJ
3025 break;
3026 case MGMT_OP_REMOVE_REMOTE_OOB_DATA:
650f726d 3027 err = remove_remote_oob_data(sk, index, cp, len);
2763eda6 3028 break;
14a53664 3029 case MGMT_OP_START_DISCOVERY:
650f726d 3030 err = start_discovery(sk, index, cp, len);
14a53664
JH
3031 break;
3032 case MGMT_OP_STOP_DISCOVERY:
d930650b 3033 err = stop_discovery(sk, index, cp, len);
14a53664 3034 break;
561aafbc 3035 case MGMT_OP_CONFIRM_NAME:
650f726d 3036 err = confirm_name(sk, index, cp, len);
561aafbc 3037 break;
7fbec224 3038 case MGMT_OP_BLOCK_DEVICE:
650f726d 3039 err = block_device(sk, index, cp, len);
7fbec224
AJ
3040 break;
3041 case MGMT_OP_UNBLOCK_DEVICE:
650f726d 3042 err = unblock_device(sk, index, cp, len);
7fbec224 3043 break;
346af67b
VCG
3044 case MGMT_OP_LOAD_LONG_TERM_KEYS:
3045 err = load_long_term_keys(sk, index, cp, len);
3046 break;
0381101f
JH
3047 default:
3048 BT_DBG("Unknown op %u", opcode);
ca69b795
JH
3049 err = cmd_status(sk, index, opcode,
3050 MGMT_STATUS_UNKNOWN_COMMAND);
0381101f
JH
3051 break;
3052 }
3053
e41d8b4e
JH
3054 if (err < 0)
3055 goto done;
3056
0381101f
JH
3057 err = msglen;
3058
3059done:
3060 kfree(buf);
3061 return err;
3062}
c71e97bf 3063
b24752fe
JH
3064static void cmd_status_rsp(struct pending_cmd *cmd, void *data)
3065{
3066 u8 *status = data;
3067
3068 cmd_status(cmd->sk, cmd->index, cmd->opcode, *status);
3069 mgmt_pending_remove(cmd);
3070}
3071
744cf19e 3072int mgmt_index_added(struct hci_dev *hdev)
c71e97bf 3073{
744cf19e 3074 return mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL);
c71e97bf
JH
3075}
3076
744cf19e 3077int mgmt_index_removed(struct hci_dev *hdev)
c71e97bf 3078{
b24752fe
JH
3079 u8 status = ENODEV;
3080
744cf19e 3081 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
b24752fe 3082
744cf19e 3083 return mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL);
eec8d2bc
JH
3084}
3085
73f22f62 3086struct cmd_lookup {
eec8d2bc 3087 struct sock *sk;
69ab39ea 3088 struct hci_dev *hdev;
eec8d2bc
JH
3089};
3090
69ab39ea 3091static void settings_rsp(struct pending_cmd *cmd, void *data)
eec8d2bc 3092{
73f22f62 3093 struct cmd_lookup *match = data;
eec8d2bc 3094
69ab39ea 3095 send_settings_rsp(cmd->sk, cmd->opcode, match->hdev);
eec8d2bc
JH
3096
3097 list_del(&cmd->list);
3098
3099 if (match->sk == NULL) {
3100 match->sk = cmd->sk;
3101 sock_hold(match->sk);
3102 }
3103
3104 mgmt_pending_free(cmd);
c71e97bf 3105}
5add6af8 3106
744cf19e 3107int mgmt_powered(struct hci_dev *hdev, u8 powered)
5add6af8 3108{
76a7f3a4 3109 struct cmd_lookup match = { NULL, hdev };
7bb895d6 3110 int err;
5add6af8 3111
5e5282bb
JH
3112 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
3113 return 0;
3114
69ab39ea 3115 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
5add6af8 3116
5e5282bb
JH
3117 if (powered) {
3118 u8 scan = 0;
3119
3120 if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags))
3121 scan |= SCAN_PAGE;
3122 if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
3123 scan |= SCAN_INQUIRY;
3124
3125 if (scan)
3126 hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
504c8dcd
JH
3127
3128 update_class(hdev);
3129 update_eir(hdev);
5e5282bb 3130 } else {
b24752fe 3131 u8 status = ENETDOWN;
744cf19e 3132 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
b24752fe
JH
3133 }
3134
beadb2bd 3135 err = new_settings(hdev, match.sk);
eec8d2bc
JH
3136
3137 if (match.sk)
3138 sock_put(match.sk);
3139
7bb895d6 3140 return err;
5add6af8 3141}
73f22f62 3142
744cf19e 3143int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
73f22f62 3144{
76a7f3a4 3145 struct cmd_lookup match = { NULL, hdev };
5e5282bb
JH
3146 bool changed = false;
3147 int err = 0;
73f22f62 3148
5e5282bb
JH
3149 if (discoverable) {
3150 if (!test_and_set_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
3151 changed = true;
3152 } else {
3153 if (test_and_clear_bit(HCI_DISCOVERABLE, &hdev->dev_flags))
3154 changed = true;
3155 }
73f22f62 3156
ed9b5f2f
JH
3157 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, settings_rsp,
3158 &match);
3159
beadb2bd
JH
3160 if (changed)
3161 err = new_settings(hdev, match.sk);
5e5282bb 3162
73f22f62
JH
3163 if (match.sk)
3164 sock_put(match.sk);
3165
7bb895d6 3166 return err;
73f22f62 3167}
9fbcbb45 3168
744cf19e 3169int mgmt_connectable(struct hci_dev *hdev, u8 connectable)
9fbcbb45 3170{
76a7f3a4 3171 struct cmd_lookup match = { NULL, hdev };
5e5282bb
JH
3172 bool changed = false;
3173 int err = 0;
9fbcbb45 3174
5e5282bb
JH
3175 if (connectable) {
3176 if (!test_and_set_bit(HCI_CONNECTABLE, &hdev->dev_flags))
3177 changed = true;
3178 } else {
3179 if (test_and_clear_bit(HCI_CONNECTABLE, &hdev->dev_flags))
3180 changed = true;
3181 }
9fbcbb45 3182
ed9b5f2f
JH
3183 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, settings_rsp,
3184 &match);
3185
beadb2bd
JH
3186 if (changed)
3187 err = new_settings(hdev, match.sk);
9fbcbb45
JH
3188
3189 if (match.sk)
3190 sock_put(match.sk);
3191
7bb895d6 3192 return err;
9fbcbb45 3193}
55ed8ca1 3194
744cf19e 3195int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status)
2d7cee58 3196{
ca69b795
JH
3197 u8 mgmt_err = mgmt_status(status);
3198
2d7cee58 3199 if (scan & SCAN_PAGE)
744cf19e 3200 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev,
ca69b795 3201 cmd_status_rsp, &mgmt_err);
2d7cee58
JH
3202
3203 if (scan & SCAN_INQUIRY)
744cf19e 3204 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev,
ca69b795 3205 cmd_status_rsp, &mgmt_err);
2d7cee58
JH
3206
3207 return 0;
3208}
3209
744cf19e
JH
3210int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
3211 u8 persistent)
55ed8ca1 3212{
86742e1e 3213 struct mgmt_ev_new_link_key ev;
55ed8ca1 3214
a492cd52 3215 memset(&ev, 0, sizeof(ev));
55ed8ca1 3216
a492cd52 3217 ev.store_hint = persistent;
d753fdc4
JH
3218 bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
3219 ev.key.addr.type = MGMT_ADDR_BREDR;
a492cd52
VCG
3220 ev.key.type = key->type;
3221 memcpy(ev.key.val, key->val, 16);
3222 ev.key.pin_len = key->pin_len;
55ed8ca1 3223
744cf19e 3224 return mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL);
55ed8ca1 3225}
f7520543 3226
346af67b
VCG
3227int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent)
3228{
3229 struct mgmt_ev_new_long_term_key ev;
3230
3231 memset(&ev, 0, sizeof(ev));
3232
3233 ev.store_hint = persistent;
3234 bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
3235 ev.key.addr.type = key->bdaddr_type;
3236 ev.key.authenticated = key->authenticated;
3237 ev.key.enc_size = key->enc_size;
3238 ev.key.ediv = key->ediv;
3239
3240 if (key->type == HCI_SMP_LTK)
3241 ev.key.master = 1;
3242
3243 memcpy(ev.key.rand, key->rand, sizeof(key->rand));
3244 memcpy(ev.key.val, key->val, sizeof(key->val));
3245
3246 return mgmt_event(MGMT_EV_NEW_LONG_TERM_KEY, hdev,
3247 &ev, sizeof(ev), NULL);
3248}
3249
afc747a6 3250int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
b644ba33
JH
3251 u8 addr_type, u8 *name, u8 name_len,
3252 u8 *dev_class)
f7520543 3253{
b644ba33
JH
3254 char buf[512];
3255 struct mgmt_ev_device_connected *ev = (void *) buf;
3256 u16 eir_len = 0;
f7520543 3257
b644ba33
JH
3258 bacpy(&ev->addr.bdaddr, bdaddr);
3259 ev->addr.type = link_to_mgmt(link_type, addr_type);
f7520543 3260
b644ba33
JH
3261 if (name_len > 0)
3262 eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE,
3263 name, name_len);
3264
3265 if (dev_class && memcmp(dev_class, "\0\0\0", 3) != 0)
3266 eir_len = eir_append_data(&ev->eir[eir_len], eir_len,
3267 EIR_CLASS_OF_DEV, dev_class, 3);
3268
3269 put_unaligned_le16(eir_len, &ev->eir_len);
3270
3271 return mgmt_event(MGMT_EV_DEVICE_CONNECTED, hdev, buf,
3272 sizeof(*ev) + eir_len, NULL);
f7520543
JH
3273}
3274
8962ee74
JH
3275static void disconnect_rsp(struct pending_cmd *cmd, void *data)
3276{
c68fb7ff 3277 struct mgmt_cp_disconnect *cp = cmd->param;
8962ee74 3278 struct sock **sk = data;
a38528f1 3279 struct mgmt_rp_disconnect rp;
8962ee74 3280
88c3df13
JH
3281 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
3282 rp.addr.type = cp->addr.type;
8962ee74 3283
aee9b218
JH
3284 cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, 0, &rp,
3285 sizeof(rp));
8962ee74
JH
3286
3287 *sk = cmd->sk;
3288 sock_hold(*sk);
3289
a664b5bc 3290 mgmt_pending_remove(cmd);
8962ee74
JH
3291}
3292
124f6e35 3293static void unpair_device_rsp(struct pending_cmd *cmd, void *data)
a8a1d19e 3294{
b1078ad0 3295 struct hci_dev *hdev = data;
124f6e35
JH
3296 struct mgmt_cp_unpair_device *cp = cmd->param;
3297 struct mgmt_rp_unpair_device rp;
a8a1d19e
JH
3298
3299 memset(&rp, 0, sizeof(rp));
124f6e35
JH
3300 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
3301 rp.addr.type = cp->addr.type;
a8a1d19e 3302
b1078ad0
JH
3303 device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, cmd->sk);
3304
aee9b218 3305 cmd_complete(cmd->sk, cmd->index, cmd->opcode, 0, &rp, sizeof(rp));
a8a1d19e
JH
3306
3307 mgmt_pending_remove(cmd);
3308}
3309
afc747a6
JH
3310int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
3311 u8 link_type, u8 addr_type)
f7520543 3312{
4c659c39 3313 struct mgmt_addr_info ev;
8962ee74
JH
3314 struct sock *sk = NULL;
3315 int err;
3316
744cf19e 3317 mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk);
f7520543 3318
f7520543 3319 bacpy(&ev.bdaddr, bdaddr);
48264f06 3320 ev.type = link_to_mgmt(link_type, addr_type);
f7520543 3321
afc747a6
JH
3322 err = mgmt_event(MGMT_EV_DEVICE_DISCONNECTED, hdev, &ev, sizeof(ev),
3323 sk);
8962ee74
JH
3324
3325 if (sk)
3326 sock_put(sk);
3327
124f6e35 3328 mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp,
b1078ad0 3329 hdev);
a8a1d19e 3330
8962ee74
JH
3331 return err;
3332}
3333
88c3df13
JH
3334int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
3335 u8 link_type, u8 addr_type, u8 status)
8962ee74 3336{
88c3df13 3337 struct mgmt_rp_disconnect rp;
8962ee74
JH
3338 struct pending_cmd *cmd;
3339 int err;
3340
2e58ef3e 3341 cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev);
8962ee74
JH
3342 if (!cmd)
3343 return -ENOENT;
3344
88c3df13
JH
3345 bacpy(&rp.addr.bdaddr, bdaddr);
3346 rp.addr.type = link_to_mgmt(link_type, addr_type);
37d9ef76 3347
88c3df13 3348 err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT,
aee9b218 3349 mgmt_status(status), &rp, sizeof(rp));
8962ee74 3350
a664b5bc 3351 mgmt_pending_remove(cmd);
8962ee74 3352
b1078ad0
JH
3353 mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp,
3354 hdev);
8962ee74 3355 return err;
f7520543 3356}
17d5c04c 3357
48264f06
JH
3358int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
3359 u8 addr_type, u8 status)
17d5c04c
JH
3360{
3361 struct mgmt_ev_connect_failed ev;
3362
4c659c39 3363 bacpy(&ev.addr.bdaddr, bdaddr);
48264f06 3364 ev.addr.type = link_to_mgmt(link_type, addr_type);
ca69b795 3365 ev.status = mgmt_status(status);
17d5c04c 3366
744cf19e 3367 return mgmt_event(MGMT_EV_CONNECT_FAILED, hdev, &ev, sizeof(ev), NULL);
17d5c04c 3368}
980e1a53 3369
744cf19e 3370int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure)
980e1a53
JH
3371{
3372 struct mgmt_ev_pin_code_request ev;
3373
d8457698
JH
3374 bacpy(&ev.addr.bdaddr, bdaddr);
3375 ev.addr.type = MGMT_ADDR_BREDR;
a770bb5a 3376 ev.secure = secure;
980e1a53 3377
744cf19e 3378 return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, hdev, &ev, sizeof(ev),
4e51eae9 3379 NULL);
980e1a53
JH
3380}
3381
744cf19e
JH
3382int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
3383 u8 status)
980e1a53
JH
3384{
3385 struct pending_cmd *cmd;
ac56fb13 3386 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
3387 int err;
3388
2e58ef3e 3389 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev);
980e1a53
JH
3390 if (!cmd)
3391 return -ENOENT;
3392
d8457698
JH
3393 bacpy(&rp.addr.bdaddr, bdaddr);
3394 rp.addr.type = MGMT_ADDR_BREDR;
ac56fb13 3395
aee9b218
JH
3396 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_REPLY,
3397 mgmt_status(status), &rp, sizeof(rp));
980e1a53 3398
a664b5bc 3399 mgmt_pending_remove(cmd);
980e1a53
JH
3400
3401 return err;
3402}
3403
744cf19e
JH
3404int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
3405 u8 status)
980e1a53
JH
3406{
3407 struct pending_cmd *cmd;
ac56fb13 3408 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
3409 int err;
3410
2e58ef3e 3411 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev);
980e1a53
JH
3412 if (!cmd)
3413 return -ENOENT;
3414
d8457698
JH
3415 bacpy(&rp.addr.bdaddr, bdaddr);
3416 rp.addr.type = MGMT_ADDR_BREDR;
ac56fb13 3417
aee9b218
JH
3418 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY,
3419 mgmt_status(status), &rp, sizeof(rp));
980e1a53 3420
a664b5bc 3421 mgmt_pending_remove(cmd);
980e1a53
JH
3422
3423 return err;
3424}
a5c29683 3425
744cf19e 3426int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
272d90df
JH
3427 u8 link_type, u8 addr_type, __le32 value,
3428 u8 confirm_hint)
a5c29683
JH
3429{
3430 struct mgmt_ev_user_confirm_request ev;
3431
744cf19e 3432 BT_DBG("%s", hdev->name);
a5c29683 3433
272d90df
JH
3434 bacpy(&ev.addr.bdaddr, bdaddr);
3435 ev.addr.type = link_to_mgmt(link_type, addr_type);
55bc1a37 3436 ev.confirm_hint = confirm_hint;
a5c29683
JH
3437 put_unaligned_le32(value, &ev.value);
3438
744cf19e 3439 return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, hdev, &ev, sizeof(ev),
4e51eae9 3440 NULL);
a5c29683
JH
3441}
3442
272d90df
JH
3443int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
3444 u8 link_type, u8 addr_type)
604086b7
BG
3445{
3446 struct mgmt_ev_user_passkey_request ev;
3447
3448 BT_DBG("%s", hdev->name);
3449
272d90df
JH
3450 bacpy(&ev.addr.bdaddr, bdaddr);
3451 ev.addr.type = link_to_mgmt(link_type, addr_type);
604086b7
BG
3452
3453 return mgmt_event(MGMT_EV_USER_PASSKEY_REQUEST, hdev, &ev, sizeof(ev),
3454 NULL);
3455}
3456
0df4c185 3457static int user_pairing_resp_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
272d90df
JH
3458 u8 link_type, u8 addr_type, u8 status,
3459 u8 opcode)
a5c29683
JH
3460{
3461 struct pending_cmd *cmd;
3462 struct mgmt_rp_user_confirm_reply rp;
3463 int err;
3464
2e58ef3e 3465 cmd = mgmt_pending_find(opcode, hdev);
a5c29683
JH
3466 if (!cmd)
3467 return -ENOENT;
3468
272d90df
JH
3469 bacpy(&rp.addr.bdaddr, bdaddr);
3470 rp.addr.type = link_to_mgmt(link_type, addr_type);
aee9b218
JH
3471 err = cmd_complete(cmd->sk, hdev->id, opcode, mgmt_status(status),
3472 &rp, sizeof(rp));
a5c29683 3473
a664b5bc 3474 mgmt_pending_remove(cmd);
a5c29683
JH
3475
3476 return err;
3477}
3478
744cf19e 3479int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
272d90df 3480 u8 link_type, u8 addr_type, u8 status)
a5c29683 3481{
272d90df
JH
3482 return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type,
3483 status, MGMT_OP_USER_CONFIRM_REPLY);
a5c29683
JH
3484}
3485
272d90df
JH
3486int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
3487 u8 link_type, u8 addr_type, u8 status)
a5c29683 3488{
272d90df
JH
3489 return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type,
3490 status, MGMT_OP_USER_CONFIRM_NEG_REPLY);
a5c29683 3491}
2a611692 3492
604086b7 3493int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
272d90df 3494 u8 link_type, u8 addr_type, u8 status)
604086b7 3495{
272d90df
JH
3496 return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type,
3497 status, MGMT_OP_USER_PASSKEY_REPLY);
604086b7
BG
3498}
3499
272d90df
JH
3500int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
3501 u8 link_type, u8 addr_type, u8 status)
604086b7 3502{
272d90df
JH
3503 return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type,
3504 status, MGMT_OP_USER_PASSKEY_NEG_REPLY);
604086b7
BG
3505}
3506
bab73cb6
JH
3507int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
3508 u8 addr_type, u8 status)
2a611692
JH
3509{
3510 struct mgmt_ev_auth_failed ev;
3511
bab73cb6
JH
3512 bacpy(&ev.addr.bdaddr, bdaddr);
3513 ev.addr.type = link_to_mgmt(link_type, addr_type);
ca69b795 3514 ev.status = mgmt_status(status);
2a611692 3515
744cf19e 3516 return mgmt_event(MGMT_EV_AUTH_FAILED, hdev, &ev, sizeof(ev), NULL);
2a611692 3517}
b312b161 3518
33ef95ed
JH
3519int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
3520{
3521 struct cmd_lookup match = { NULL, hdev };
47990ea0
JH
3522 bool changed = false;
3523 int err = 0;
33ef95ed
JH
3524
3525 if (status) {
3526 u8 mgmt_err = mgmt_status(status);
3527 mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev,
3528 cmd_status_rsp, &mgmt_err);
3529 return 0;
3530 }
3531
47990ea0
JH
3532 if (test_bit(HCI_AUTH, &hdev->flags)) {
3533 if (!test_and_set_bit(HCI_LINK_SECURITY, &hdev->dev_flags))
3534 changed = true;
3535 } else {
3536 if (test_and_clear_bit(HCI_LINK_SECURITY, &hdev->dev_flags))
3537 changed = true;
3538 }
3539
33ef95ed
JH
3540 mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp,
3541 &match);
3542
47990ea0
JH
3543 if (changed)
3544 err = new_settings(hdev, match.sk);
33ef95ed
JH
3545
3546 if (match.sk)
3547 sock_put(match.sk);
3548
3549 return err;
3550}
3551
cacaf52f
JH
3552static int clear_eir(struct hci_dev *hdev)
3553{
3554 struct hci_cp_write_eir cp;
3555
3556 if (!(hdev->features[6] & LMP_EXT_INQ))
3557 return 0;
3558
c80da27e
JH
3559 memset(hdev->eir, 0, sizeof(hdev->eir));
3560
cacaf52f
JH
3561 memset(&cp, 0, sizeof(cp));
3562
3563 return hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
3564}
3565
c0ecddc2 3566int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
ed2c4ee3
JH
3567{
3568 struct cmd_lookup match = { NULL, hdev };
c0ecddc2
JH
3569 bool changed = false;
3570 int err = 0;
ed2c4ee3
JH
3571
3572 if (status) {
3573 u8 mgmt_err = mgmt_status(status);
c0ecddc2
JH
3574
3575 if (enable && test_and_clear_bit(HCI_SSP_ENABLED,
3576 &hdev->dev_flags))
3577 err = new_settings(hdev, NULL);
3578
ed2c4ee3
JH
3579 mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev,
3580 cmd_status_rsp, &mgmt_err);
c0ecddc2
JH
3581
3582 return err;
3583 }
3584
3585 if (enable) {
3586 if (!test_and_set_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
3587 changed = true;
3588 } else {
3589 if (test_and_clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
3590 changed = true;
ed2c4ee3
JH
3591 }
3592
3593 mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match);
3594
c0ecddc2
JH
3595 if (changed)
3596 err = new_settings(hdev, match.sk);
ed2c4ee3 3597
5fc6ebb1 3598 if (match.sk)
ed2c4ee3
JH
3599 sock_put(match.sk);
3600
5fc6ebb1
JH
3601 if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags))
3602 update_eir(hdev);
3603 else
3604 clear_eir(hdev);
cacaf52f 3605
ed2c4ee3
JH
3606 return err;
3607}
3608
7f9a903c
MH
3609int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
3610 u8 status)
3611{
3612 int err;
3613
3614 err = mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class, 3, NULL);
3615
3616 return err;
3617}
3618
744cf19e 3619int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status)
b312b161
JH
3620{
3621 struct pending_cmd *cmd;
3622 struct mgmt_cp_set_local_name ev;
28cc7bde
JH
3623 bool changed = false;
3624 int err = 0;
3625
3626 if (memcmp(name, hdev->dev_name, sizeof(hdev->dev_name)) != 0) {
3627 memcpy(hdev->dev_name, name, sizeof(hdev->dev_name));
3628 changed = true;
3629 }
b312b161
JH
3630
3631 memset(&ev, 0, sizeof(ev));
3632 memcpy(ev.name, name, HCI_MAX_NAME_LENGTH);
28cc7bde 3633 memcpy(ev.short_name, hdev->short_name, HCI_MAX_SHORT_NAME_LENGTH);
b312b161 3634
2e58ef3e 3635 cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev);
b312b161
JH
3636 if (!cmd)
3637 goto send_event;
3638
7bdaae4a
JH
3639 /* Always assume that either the short or the complete name has
3640 * changed if there was a pending mgmt command */
3641 changed = true;
3642
b312b161 3643 if (status) {
744cf19e 3644 err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
ca69b795 3645 mgmt_status(status));
b312b161
JH
3646 goto failed;
3647 }
3648
aee9b218 3649 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0, &ev,
b312b161
JH
3650 sizeof(ev));
3651 if (err < 0)
3652 goto failed;
3653
3654send_event:
28cc7bde
JH
3655 if (changed)
3656 err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev,
3657 sizeof(ev), cmd ? cmd->sk : NULL);
3658
f51d5b24 3659 update_eir(hdev);
b312b161
JH
3660
3661failed:
3662 if (cmd)
3663 mgmt_pending_remove(cmd);
3664 return err;
3665}
c35938b2 3666
744cf19e
JH
3667int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
3668 u8 *randomizer, u8 status)
c35938b2
SJ
3669{
3670 struct pending_cmd *cmd;
3671 int err;
3672
744cf19e 3673 BT_DBG("%s status %u", hdev->name, status);
c35938b2 3674
2e58ef3e 3675 cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev);
c35938b2
SJ
3676 if (!cmd)
3677 return -ENOENT;
3678
3679 if (status) {
744cf19e 3680 err = cmd_status(cmd->sk, hdev->id,
ca69b795
JH
3681 MGMT_OP_READ_LOCAL_OOB_DATA,
3682 mgmt_status(status));
c35938b2
SJ
3683 } else {
3684 struct mgmt_rp_read_local_oob_data rp;
3685
3686 memcpy(rp.hash, hash, sizeof(rp.hash));
3687 memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer));
3688
744cf19e
JH
3689 err = cmd_complete(cmd->sk, hdev->id,
3690 MGMT_OP_READ_LOCAL_OOB_DATA,
aee9b218 3691 0, &rp, sizeof(rp));
c35938b2
SJ
3692 }
3693
3694 mgmt_pending_remove(cmd);
3695
3696 return err;
3697}
e17acd40 3698
06199cf8
JH
3699int mgmt_le_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
3700{
3701 struct cmd_lookup match = { NULL, hdev };
3702 bool changed = false;
3703 int err = 0;
3704
3705 if (status) {
3706 u8 mgmt_err = mgmt_status(status);
3707
3708 if (enable && test_and_clear_bit(HCI_LE_ENABLED,
3709 &hdev->dev_flags))
3710 err = new_settings(hdev, NULL);
3711
3712 mgmt_pending_foreach(MGMT_OP_SET_LE, hdev,
3713 cmd_status_rsp, &mgmt_err);
3714
3715 return err;
3716 }
3717
3718 if (enable) {
3719 if (!test_and_set_bit(HCI_LE_ENABLED, &hdev->dev_flags))
3720 changed = true;
3721 } else {
3722 if (test_and_clear_bit(HCI_LE_ENABLED, &hdev->dev_flags))
3723 changed = true;
3724 }
3725
3726 mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, settings_rsp, &match);
3727
3728 if (changed)
3729 err = new_settings(hdev, match.sk);
3730
3731 if (match.sk)
3732 sock_put(match.sk);
3733
3734 return err;
3735}
3736
48264f06 3737int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
561aafbc 3738 u8 addr_type, u8 *dev_class, s8 rssi,
388fc8fa 3739 u8 cfm_name, u8 ssp, u8 *eir, u16 eir_len)
e17acd40 3740{
e319d2e7
JH
3741 char buf[512];
3742 struct mgmt_ev_device_found *ev = (void *) buf;
1dc06093 3743 size_t ev_size;
e17acd40 3744
1dc06093
JH
3745 /* Leave 5 bytes for a potential CoD field */
3746 if (sizeof(*ev) + eir_len + 5 > sizeof(buf))
7d262f86
AG
3747 return -EINVAL;
3748
1dc06093
JH
3749 memset(buf, 0, sizeof(buf));
3750
e319d2e7
JH
3751 bacpy(&ev->addr.bdaddr, bdaddr);
3752 ev->addr.type = link_to_mgmt(link_type, addr_type);
3753 ev->rssi = rssi;
9a395a80
JH
3754 if (cfm_name)
3755 ev->flags[0] |= MGMT_DEV_FOUND_CONFIRM_NAME;
388fc8fa
JH
3756 if (!ssp)
3757 ev->flags[0] |= MGMT_DEV_FOUND_LEGACY_PAIRING;
e17acd40 3758
1dc06093 3759 if (eir_len > 0)
e319d2e7 3760 memcpy(ev->eir, eir, eir_len);
e17acd40 3761
1dc06093
JH
3762 if (dev_class && !eir_has_data_type(ev->eir, eir_len, EIR_CLASS_OF_DEV))
3763 eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV,
3764 dev_class, 3);
3765
3766 put_unaligned_le16(eir_len, &ev->eir_len);
3767
3768 ev_size = sizeof(*ev) + eir_len;
f8523598 3769
e319d2e7 3770 return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL);
e17acd40 3771}
a88a9652 3772
b644ba33
JH
3773int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
3774 u8 addr_type, s8 rssi, u8 *name, u8 name_len)
a88a9652 3775{
b644ba33
JH
3776 struct mgmt_ev_device_found *ev;
3777 char buf[sizeof(*ev) + HCI_MAX_NAME_LENGTH + 2];
3778 u16 eir_len;
a88a9652 3779
b644ba33 3780 ev = (struct mgmt_ev_device_found *) buf;
a88a9652 3781
b644ba33
JH
3782 memset(buf, 0, sizeof(buf));
3783
3784 bacpy(&ev->addr.bdaddr, bdaddr);
3785 ev->addr.type = link_to_mgmt(link_type, addr_type);
3786 ev->rssi = rssi;
3787
3788 eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, name,
3789 name_len);
3790
3791 put_unaligned_le16(eir_len, &ev->eir_len);
a88a9652 3792
053c7e0c
JH
3793 return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev,
3794 sizeof(*ev) + eir_len, NULL);
a88a9652 3795}
314b2381 3796
7a135109 3797int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status)
164a6e78
JH
3798{
3799 struct pending_cmd *cmd;
f808e166 3800 u8 type;
164a6e78
JH
3801 int err;
3802
203159d4
AG
3803 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
3804
2e58ef3e 3805 cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev);
164a6e78
JH
3806 if (!cmd)
3807 return -ENOENT;
3808
f808e166
JH
3809 type = hdev->discovery.type;
3810
3811 err = cmd_complete(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status),
3812 &type, sizeof(type));
164a6e78
JH
3813 mgmt_pending_remove(cmd);
3814
3815 return err;
3816}
3817
e6d465cb
AG
3818int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status)
3819{
3820 struct pending_cmd *cmd;
3821 int err;
3822
3823 cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev);
3824 if (!cmd)
3825 return -ENOENT;
3826
d930650b
JH
3827 err = cmd_complete(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status),
3828 &hdev->discovery.type,
3829 sizeof(hdev->discovery.type));
164a6e78
JH
3830 mgmt_pending_remove(cmd);
3831
3832 return err;
3833}
3834
744cf19e 3835int mgmt_discovering(struct hci_dev *hdev, u8 discovering)
314b2381 3836{
f963e8e9 3837 struct mgmt_ev_discovering ev;
164a6e78
JH
3838 struct pending_cmd *cmd;
3839
343fb145
AG
3840 BT_DBG("%s discovering %u", hdev->name, discovering);
3841
164a6e78 3842 if (discovering)
2e58ef3e 3843 cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev);
164a6e78 3844 else
2e58ef3e 3845 cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev);
164a6e78
JH
3846
3847 if (cmd != NULL) {
f808e166
JH
3848 u8 type = hdev->discovery.type;
3849
d930650b 3850 cmd_complete(cmd->sk, hdev->id, cmd->opcode, 0,
f808e166 3851 &type, sizeof(type));
164a6e78
JH
3852 mgmt_pending_remove(cmd);
3853 }
3854
f963e8e9
JH
3855 memset(&ev, 0, sizeof(ev));
3856 ev.type = hdev->discovery.type;
3857 ev.discovering = discovering;
3858
3859 return mgmt_event(MGMT_EV_DISCOVERING, hdev, &ev, sizeof(ev), NULL);
314b2381 3860}
5e762444 3861
88c1fe4b 3862int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
5e762444
AJ
3863{
3864 struct pending_cmd *cmd;
3865 struct mgmt_ev_device_blocked ev;
3866
2e58ef3e 3867 cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, hdev);
5e762444 3868
88c1fe4b
JH
3869 bacpy(&ev.addr.bdaddr, bdaddr);
3870 ev.addr.type = type;
5e762444 3871
744cf19e
JH
3872 return mgmt_event(MGMT_EV_DEVICE_BLOCKED, hdev, &ev, sizeof(ev),
3873 cmd ? cmd->sk : NULL);
5e762444
AJ
3874}
3875
88c1fe4b 3876int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
5e762444
AJ
3877{
3878 struct pending_cmd *cmd;
3879 struct mgmt_ev_device_unblocked ev;
3880
2e58ef3e 3881 cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, hdev);
5e762444 3882
88c1fe4b
JH
3883 bacpy(&ev.addr.bdaddr, bdaddr);
3884 ev.addr.type = type;
5e762444 3885
744cf19e
JH
3886 return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &ev, sizeof(ev),
3887 cmd ? cmd->sk : NULL);
5e762444 3888}
d7b7e796
MH
3889
3890module_param(enable_hs, bool, 0644);
3891MODULE_PARM_DESC(enable_hs, "Enable High Speed support");
3892
3893module_param(enable_le, bool, 0644);
3894MODULE_PARM_DESC(enable_le, "Enable Low Energy support");