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