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