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