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