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