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