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