Bluetooth: Always enable management interface
[deliverable/linux.git] / net / bluetooth / mgmt.c
CommitLineData
0381101f
JH
1/*
2 BlueZ - Bluetooth protocol stack for Linux
ea585ab5 3
0381101f 4 Copyright (C) 2010 Nokia Corporation
ea585ab5 5 Copyright (C) 2011-2012 Intel Corporation
0381101f
JH
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
15 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
22 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI Management interface */
26
ca69b795 27#include <linux/kernel.h>
72359753 28#include <linux/uaccess.h>
3a9a231d 29#include <linux/module.h>
0381101f
JH
30#include <asm/unaligned.h>
31
32#include <net/bluetooth/bluetooth.h>
33#include <net/bluetooth/hci_core.h>
34#include <net/bluetooth/mgmt.h>
5fe57d9e 35#include <net/bluetooth/smp.h>
0381101f 36
d7b7e796
MH
37bool enable_hs;
38bool enable_le;
39
2da9c55c
JH
40#define MGMT_VERSION 1
41#define MGMT_REVISION 0
02d98129 42
e70bb2e8
JH
43static const u16 mgmt_commands[] = {
44 MGMT_OP_READ_INDEX_LIST,
45 MGMT_OP_READ_INFO,
46 MGMT_OP_SET_POWERED,
47 MGMT_OP_SET_DISCOVERABLE,
48 MGMT_OP_SET_CONNECTABLE,
49 MGMT_OP_SET_FAST_CONNECTABLE,
50 MGMT_OP_SET_PAIRABLE,
51 MGMT_OP_SET_LINK_SECURITY,
52 MGMT_OP_SET_SSP,
53 MGMT_OP_SET_HS,
54 MGMT_OP_SET_LE,
55 MGMT_OP_SET_DEV_CLASS,
56 MGMT_OP_SET_LOCAL_NAME,
57 MGMT_OP_ADD_UUID,
58 MGMT_OP_REMOVE_UUID,
59 MGMT_OP_LOAD_LINK_KEYS,
60 MGMT_OP_LOAD_LONG_TERM_KEYS,
61 MGMT_OP_DISCONNECT,
62 MGMT_OP_GET_CONNECTIONS,
63 MGMT_OP_PIN_CODE_REPLY,
64 MGMT_OP_PIN_CODE_NEG_REPLY,
65 MGMT_OP_SET_IO_CAPABILITY,
66 MGMT_OP_PAIR_DEVICE,
67 MGMT_OP_CANCEL_PAIR_DEVICE,
68 MGMT_OP_UNPAIR_DEVICE,
69 MGMT_OP_USER_CONFIRM_REPLY,
70 MGMT_OP_USER_CONFIRM_NEG_REPLY,
71 MGMT_OP_USER_PASSKEY_REPLY,
72 MGMT_OP_USER_PASSKEY_NEG_REPLY,
73 MGMT_OP_READ_LOCAL_OOB_DATA,
74 MGMT_OP_ADD_REMOTE_OOB_DATA,
75 MGMT_OP_REMOVE_REMOTE_OOB_DATA,
76 MGMT_OP_START_DISCOVERY,
77 MGMT_OP_STOP_DISCOVERY,
78 MGMT_OP_CONFIRM_NAME,
79 MGMT_OP_BLOCK_DEVICE,
80 MGMT_OP_UNBLOCK_DEVICE,
81};
82
83static const u16 mgmt_events[] = {
84 MGMT_EV_CONTROLLER_ERROR,
85 MGMT_EV_INDEX_ADDED,
86 MGMT_EV_INDEX_REMOVED,
87 MGMT_EV_NEW_SETTINGS,
88 MGMT_EV_CLASS_OF_DEV_CHANGED,
89 MGMT_EV_LOCAL_NAME_CHANGED,
90 MGMT_EV_NEW_LINK_KEY,
91 MGMT_EV_NEW_LONG_TERM_KEY,
92 MGMT_EV_DEVICE_CONNECTED,
93 MGMT_EV_DEVICE_DISCONNECTED,
94 MGMT_EV_CONNECT_FAILED,
95 MGMT_EV_PIN_CODE_REQUEST,
96 MGMT_EV_USER_CONFIRM_REQUEST,
97 MGMT_EV_USER_PASSKEY_REQUEST,
98 MGMT_EV_AUTH_FAILED,
99 MGMT_EV_DEVICE_FOUND,
100 MGMT_EV_DISCOVERING,
101 MGMT_EV_DEVICE_BLOCKED,
102 MGMT_EV_DEVICE_UNBLOCKED,
103 MGMT_EV_DEVICE_UNPAIRED,
104};
105
3fd24153
AG
106/*
107 * These LE scan and inquiry parameters were chosen according to LE General
108 * Discovery Procedure specification.
109 */
110#define LE_SCAN_TYPE 0x01
111#define LE_SCAN_WIN 0x12
112#define LE_SCAN_INT 0x12
113#define LE_SCAN_TIMEOUT_LE_ONLY 10240 /* TGAP(gen_disc_scan_min) */
5e0452c0 114#define LE_SCAN_TIMEOUT_BREDR_LE 5120 /* TGAP(100)/2 */
3fd24153 115
e8777525 116#define INQUIRY_LEN_BREDR 0x08 /* TGAP(100) */
5e0452c0 117#define INQUIRY_LEN_BREDR_LE 0x04 /* TGAP(100)/2 */
2519a1fc 118
7d78525d
JH
119#define SERVICE_CACHE_TIMEOUT (5 * 1000)
120
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
2284static int stop_discovery(struct sock *sk, u16 index)
2285{
2286 struct hci_dev *hdev;
2287 struct pending_cmd *cmd;
30dc78e1
JH
2288 struct hci_cp_remote_name_req_cancel cp;
2289 struct inquiry_entry *e;
14a53664
JH
2290 int err;
2291
2292 BT_DBG("hci%u", index);
2293
2294 hdev = hci_dev_get(index);
2295 if (!hdev)
ca69b795
JH
2296 return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY,
2297 MGMT_STATUS_INVALID_PARAMS);
14a53664 2298
09fd0de5 2299 hci_dev_lock(hdev);
14a53664 2300
30dc78e1 2301 if (!hci_discovery_active(hdev)) {
ff9ef578
JH
2302 err = cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY,
2303 MGMT_STATUS_REJECTED);
30dc78e1 2304 goto unlock;
ff9ef578
JH
2305 }
2306
2e58ef3e 2307 cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, NULL, 0);
14a53664
JH
2308 if (!cmd) {
2309 err = -ENOMEM;
30dc78e1
JH
2310 goto unlock;
2311 }
2312
343f935b 2313 if (hdev->discovery.state == DISCOVERY_FINDING) {
30dc78e1
JH
2314 err = hci_cancel_inquiry(hdev);
2315 if (err < 0)
2316 mgmt_pending_remove(cmd);
2317 else
2318 hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
2319 goto unlock;
2320 }
2321
2322 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_PENDING);
2323 if (!e) {
2324 mgmt_pending_remove(cmd);
aee9b218
JH
2325 err = cmd_complete(sk, index, MGMT_OP_STOP_DISCOVERY, 0,
2326 NULL, 0);
30dc78e1
JH
2327 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
2328 goto unlock;
14a53664
JH
2329 }
2330
30dc78e1
JH
2331 bacpy(&cp.bdaddr, &e->data.bdaddr);
2332 err = hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ_CANCEL,
2333 sizeof(cp), &cp);
14a53664
JH
2334 if (err < 0)
2335 mgmt_pending_remove(cmd);
ff9ef578
JH
2336 else
2337 hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
14a53664 2338
30dc78e1 2339unlock:
09fd0de5 2340 hci_dev_unlock(hdev);
14a53664
JH
2341 hci_dev_put(hdev);
2342
2343 return err;
2344}
2345
650f726d 2346static int confirm_name(struct sock *sk, u16 index, void *data, u16 len)
561aafbc 2347{
650f726d 2348 struct mgmt_cp_confirm_name *cp = data;
561aafbc
JH
2349 struct inquiry_entry *e;
2350 struct hci_dev *hdev;
2351 int err;
2352
2353 BT_DBG("hci%u", index);
2354
2355 if (len != sizeof(*cp))
2356 return cmd_status(sk, index, MGMT_OP_CONFIRM_NAME,
2357 MGMT_STATUS_INVALID_PARAMS);
2358
2359 hdev = hci_dev_get(index);
2360 if (!hdev)
2361 return cmd_status(sk, index, MGMT_OP_CONFIRM_NAME,
2362 MGMT_STATUS_INVALID_PARAMS);
2363
2364 hci_dev_lock(hdev);
2365
30dc78e1
JH
2366 if (!hci_discovery_active(hdev)) {
2367 err = cmd_status(sk, index, MGMT_OP_CONFIRM_NAME,
2368 MGMT_STATUS_FAILED);
2369 goto failed;
2370 }
2371
a198e7b1 2372 e = hci_inquiry_cache_lookup_unknown(hdev, &cp->addr.bdaddr);
561aafbc
JH
2373 if (!e) {
2374 err = cmd_status (sk, index, MGMT_OP_CONFIRM_NAME,
2375 MGMT_STATUS_INVALID_PARAMS);
2376 goto failed;
2377 }
2378
2379 if (cp->name_known) {
2380 e->name_state = NAME_KNOWN;
2381 list_del(&e->list);
2382 } else {
2383 e->name_state = NAME_NEEDED;
a3d4e20a 2384 hci_inquiry_cache_update_resolve(hdev, e);
561aafbc
JH
2385 }
2386
2387 err = 0;
2388
2389failed:
2390 hci_dev_unlock(hdev);
2391
2392 return err;
2393}
2394
650f726d 2395static int block_device(struct sock *sk, u16 index, void *data, u16 len)
7fbec224
AJ
2396{
2397 struct hci_dev *hdev;
650f726d 2398 struct mgmt_cp_block_device *cp = data;
f0eeea8b 2399 u8 status;
7fbec224
AJ
2400 int err;
2401
2402 BT_DBG("hci%u", index);
2403
7fbec224
AJ
2404 if (len != sizeof(*cp))
2405 return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
ca69b795 2406 MGMT_STATUS_INVALID_PARAMS);
7fbec224
AJ
2407
2408 hdev = hci_dev_get(index);
2409 if (!hdev)
f0eeea8b
JH
2410 return cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE,
2411 MGMT_STATUS_INVALID_PARAMS,
2412 &cp->addr, sizeof(cp->addr));
7fbec224 2413
09fd0de5 2414 hci_dev_lock(hdev);
5e762444 2415
88c1fe4b 2416 err = hci_blacklist_add(hdev, &cp->addr.bdaddr, cp->addr.type);
7fbec224 2417 if (err < 0)
f0eeea8b 2418 status = MGMT_STATUS_FAILED;
7fbec224 2419 else
f0eeea8b
JH
2420 status = 0;
2421
2422 err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE, status,
2423 &cp->addr, sizeof(cp->addr));
5e762444 2424
09fd0de5 2425 hci_dev_unlock(hdev);
7fbec224
AJ
2426 hci_dev_put(hdev);
2427
2428 return err;
2429}
2430
650f726d 2431static int unblock_device(struct sock *sk, u16 index, void *data, u16 len)
7fbec224
AJ
2432{
2433 struct hci_dev *hdev;
650f726d 2434 struct mgmt_cp_unblock_device *cp = data;
f0eeea8b 2435 u8 status;
7fbec224
AJ
2436 int err;
2437
2438 BT_DBG("hci%u", index);
2439
7fbec224
AJ
2440 if (len != sizeof(*cp))
2441 return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
ca69b795 2442 MGMT_STATUS_INVALID_PARAMS);
7fbec224
AJ
2443
2444 hdev = hci_dev_get(index);
2445 if (!hdev)
f0eeea8b
JH
2446 return cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE,
2447 MGMT_STATUS_INVALID_PARAMS,
2448 &cp->addr, sizeof(cp->addr));
7fbec224 2449
09fd0de5 2450 hci_dev_lock(hdev);
5e762444 2451
88c1fe4b 2452 err = hci_blacklist_del(hdev, &cp->addr.bdaddr, cp->addr.type);
7fbec224 2453 if (err < 0)
f0eeea8b 2454 status = MGMT_STATUS_INVALID_PARAMS;
7fbec224 2455 else
f0eeea8b
JH
2456 status = 0;
2457
2458 err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE, status,
2459 &cp->addr, sizeof(cp->addr));
5e762444 2460
09fd0de5 2461 hci_dev_unlock(hdev);
7fbec224
AJ
2462 hci_dev_put(hdev);
2463
2464 return err;
2465}
2466
f6422ec6 2467static int set_fast_connectable(struct sock *sk, u16 index,
650f726d 2468 void *data, u16 len)
f6422ec6
AJ
2469{
2470 struct hci_dev *hdev;
650f726d 2471 struct mgmt_mode *cp = data;
f6422ec6
AJ
2472 struct hci_cp_write_page_scan_activity acp;
2473 u8 type;
2474 int err;
2475
2476 BT_DBG("hci%u", index);
2477
2478 if (len != sizeof(*cp))
2479 return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2480 MGMT_STATUS_INVALID_PARAMS);
f6422ec6
AJ
2481
2482 hdev = hci_dev_get(index);
2483 if (!hdev)
2484 return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2485 MGMT_STATUS_INVALID_PARAMS);
f6422ec6
AJ
2486
2487 hci_dev_lock(hdev);
2488
f7c6869c 2489 if (cp->val) {
f6422ec6
AJ
2490 type = PAGE_SCAN_TYPE_INTERLACED;
2491 acp.interval = 0x0024; /* 22.5 msec page scan interval */
2492 } else {
2493 type = PAGE_SCAN_TYPE_STANDARD; /* default */
2494 acp.interval = 0x0800; /* default 1.28 sec page scan */
2495 }
2496
2497 acp.window = 0x0012; /* default 11.25 msec page scan window */
2498
2499 err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
2500 sizeof(acp), &acp);
2501 if (err < 0) {
2502 err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2503 MGMT_STATUS_FAILED);
f6422ec6
AJ
2504 goto done;
2505 }
2506
2507 err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type);
2508 if (err < 0) {
2509 err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2510 MGMT_STATUS_FAILED);
f6422ec6
AJ
2511 goto done;
2512 }
2513
aee9b218
JH
2514 err = cmd_complete(sk, index, MGMT_OP_SET_FAST_CONNECTABLE, 0,
2515 NULL, 0);
f6422ec6
AJ
2516done:
2517 hci_dev_unlock(hdev);
2518 hci_dev_put(hdev);
2519
2520 return err;
2521}
2522
346af67b
VCG
2523static int load_long_term_keys(struct sock *sk, u16 index,
2524 void *cp_data, u16 len)
2525{
2526 struct hci_dev *hdev;
2527 struct mgmt_cp_load_long_term_keys *cp = cp_data;
2528 u16 key_count, expected_len;
2529 int i;
2530
2531 if (len < sizeof(*cp))
2532 return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS,
2533 EINVAL);
2534
2535 key_count = get_unaligned_le16(&cp->key_count);
2536
2537 expected_len = sizeof(*cp) + key_count *
2538 sizeof(struct mgmt_ltk_info);
2539 if (expected_len != len) {
2540 BT_ERR("load_keys: expected %u bytes, got %u bytes",
2541 len, expected_len);
2542 return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS,
2543 EINVAL);
2544 }
2545
2546 hdev = hci_dev_get(index);
2547 if (!hdev)
2548 return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS,
2549 ENODEV);
2550
2551 BT_DBG("hci%u key_count %u", index, key_count);
2552
2553 hci_dev_lock(hdev);
2554
2555 hci_smp_ltks_clear(hdev);
2556
2557 for (i = 0; i < key_count; i++) {
2558 struct mgmt_ltk_info *key = &cp->keys[i];
2559 u8 type;
2560
2561 if (key->master)
2562 type = HCI_SMP_LTK;
2563 else
2564 type = HCI_SMP_LTK_SLAVE;
2565
2566 hci_add_ltk(hdev, &key->addr.bdaddr, key->addr.type,
2567 type, 0, key->authenticated, key->val,
2568 key->enc_size, key->ediv, key->rand);
2569 }
2570
2571 hci_dev_unlock(hdev);
2572 hci_dev_put(hdev);
2573
2574 return 0;
2575}
2576
0381101f
JH
2577int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
2578{
650f726d
VCG
2579 void *buf;
2580 u8 *cp;
0381101f 2581 struct mgmt_hdr *hdr;
4e51eae9 2582 u16 opcode, index, len;
0381101f
JH
2583 int err;
2584
2585 BT_DBG("got %zu bytes", msglen);
2586
2587 if (msglen < sizeof(*hdr))
2588 return -EINVAL;
2589
e63a15ec 2590 buf = kmalloc(msglen, GFP_KERNEL);
0381101f
JH
2591 if (!buf)
2592 return -ENOMEM;
2593
2594 if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
2595 err = -EFAULT;
2596 goto done;
2597 }
2598
650f726d 2599 hdr = buf;
0381101f 2600 opcode = get_unaligned_le16(&hdr->opcode);
4e51eae9 2601 index = get_unaligned_le16(&hdr->index);
0381101f
JH
2602 len = get_unaligned_le16(&hdr->len);
2603
2604 if (len != msglen - sizeof(*hdr)) {
2605 err = -EINVAL;
2606 goto done;
2607 }
2608
650f726d
VCG
2609 cp = buf + sizeof(*hdr);
2610
0381101f 2611 switch (opcode) {
02d98129
JH
2612 case MGMT_OP_READ_VERSION:
2613 err = read_version(sk);
2614 break;
e70bb2e8
JH
2615 case MGMT_OP_READ_COMMANDS:
2616 err = read_commands(sk);
2617 break;
faba42eb
JH
2618 case MGMT_OP_READ_INDEX_LIST:
2619 err = read_index_list(sk);
2620 break;
f7b64e69 2621 case MGMT_OP_READ_INFO:
4e51eae9 2622 err = read_controller_info(sk, index);
f7b64e69 2623 break;
eec8d2bc 2624 case MGMT_OP_SET_POWERED:
650f726d 2625 err = set_powered(sk, index, cp, len);
eec8d2bc 2626 break;
73f22f62 2627 case MGMT_OP_SET_DISCOVERABLE:
650f726d 2628 err = set_discoverable(sk, index, cp, len);
73f22f62 2629 break;
9fbcbb45 2630 case MGMT_OP_SET_CONNECTABLE:
650f726d 2631 err = set_connectable(sk, index, cp, len);
9fbcbb45 2632 break;
f7c6869c 2633 case MGMT_OP_SET_FAST_CONNECTABLE:
650f726d 2634 err = set_fast_connectable(sk, index, cp, len);
f7c6869c 2635 break;
c542a06c 2636 case MGMT_OP_SET_PAIRABLE:
650f726d 2637 err = set_pairable(sk, index, cp, len);
c542a06c 2638 break;
33ef95ed
JH
2639 case MGMT_OP_SET_LINK_SECURITY:
2640 err = set_link_security(sk, index, cp, len);
2641 break;
ed2c4ee3
JH
2642 case MGMT_OP_SET_SSP:
2643 err = set_ssp(sk, index, cp, len);
2644 break;
2aeb9a1a 2645 case MGMT_OP_ADD_UUID:
650f726d 2646 err = add_uuid(sk, index, cp, len);
2aeb9a1a
JH
2647 break;
2648 case MGMT_OP_REMOVE_UUID:
650f726d 2649 err = remove_uuid(sk, index, cp, len);
2aeb9a1a 2650 break;
1aff6f09 2651 case MGMT_OP_SET_DEV_CLASS:
650f726d 2652 err = set_dev_class(sk, index, cp, len);
1aff6f09 2653 break;
86742e1e 2654 case MGMT_OP_LOAD_LINK_KEYS:
650f726d 2655 err = load_link_keys(sk, index, cp, len);
55ed8ca1 2656 break;
8962ee74 2657 case MGMT_OP_DISCONNECT:
650f726d 2658 err = disconnect(sk, index, cp, len);
8962ee74 2659 break;
2784eb41 2660 case MGMT_OP_GET_CONNECTIONS:
8ce6284e 2661 err = get_connections(sk, index);
2784eb41 2662 break;
980e1a53 2663 case MGMT_OP_PIN_CODE_REPLY:
650f726d 2664 err = pin_code_reply(sk, index, cp, len);
980e1a53
JH
2665 break;
2666 case MGMT_OP_PIN_CODE_NEG_REPLY:
650f726d 2667 err = pin_code_neg_reply(sk, index, cp, len);
980e1a53 2668 break;
17fa4b9d 2669 case MGMT_OP_SET_IO_CAPABILITY:
650f726d 2670 err = set_io_capability(sk, index, cp, len);
17fa4b9d 2671 break;
e9a416b5 2672 case MGMT_OP_PAIR_DEVICE:
650f726d 2673 err = pair_device(sk, index, cp, len);
e9a416b5 2674 break;
28424707
JH
2675 case MGMT_OP_CANCEL_PAIR_DEVICE:
2676 err = cancel_pair_device(sk, index, buf + sizeof(*hdr), len);
2677 break;
124f6e35
JH
2678 case MGMT_OP_UNPAIR_DEVICE:
2679 err = unpair_device(sk, index, cp, len);
2680 break;
a5c29683 2681 case MGMT_OP_USER_CONFIRM_REPLY:
650f726d 2682 err = user_confirm_reply(sk, index, cp, len);
a5c29683
JH
2683 break;
2684 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
650f726d 2685 err = user_confirm_neg_reply(sk, index, cp, len);
a5c29683 2686 break;
604086b7 2687 case MGMT_OP_USER_PASSKEY_REPLY:
650f726d 2688 err = user_passkey_reply(sk, index, cp, len);
604086b7
BG
2689 break;
2690 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
650f726d 2691 err = user_passkey_neg_reply(sk, index, cp, len);
a5c29683 2692 break;
b312b161 2693 case MGMT_OP_SET_LOCAL_NAME:
650f726d 2694 err = set_local_name(sk, index, cp, len);
b312b161 2695 break;
c35938b2
SJ
2696 case MGMT_OP_READ_LOCAL_OOB_DATA:
2697 err = read_local_oob_data(sk, index);
2698 break;
2763eda6 2699 case MGMT_OP_ADD_REMOTE_OOB_DATA:
650f726d 2700 err = add_remote_oob_data(sk, index, cp, len);
2763eda6
SJ
2701 break;
2702 case MGMT_OP_REMOVE_REMOTE_OOB_DATA:
650f726d 2703 err = remove_remote_oob_data(sk, index, cp, len);
2763eda6 2704 break;
14a53664 2705 case MGMT_OP_START_DISCOVERY:
650f726d 2706 err = start_discovery(sk, index, cp, len);
14a53664
JH
2707 break;
2708 case MGMT_OP_STOP_DISCOVERY:
2709 err = stop_discovery(sk, index);
2710 break;
561aafbc 2711 case MGMT_OP_CONFIRM_NAME:
650f726d 2712 err = confirm_name(sk, index, cp, len);
561aafbc 2713 break;
7fbec224 2714 case MGMT_OP_BLOCK_DEVICE:
650f726d 2715 err = block_device(sk, index, cp, len);
7fbec224
AJ
2716 break;
2717 case MGMT_OP_UNBLOCK_DEVICE:
650f726d 2718 err = unblock_device(sk, index, cp, len);
7fbec224 2719 break;
346af67b
VCG
2720 case MGMT_OP_LOAD_LONG_TERM_KEYS:
2721 err = load_long_term_keys(sk, index, cp, len);
2722 break;
0381101f
JH
2723 default:
2724 BT_DBG("Unknown op %u", opcode);
ca69b795
JH
2725 err = cmd_status(sk, index, opcode,
2726 MGMT_STATUS_UNKNOWN_COMMAND);
0381101f
JH
2727 break;
2728 }
2729
e41d8b4e
JH
2730 if (err < 0)
2731 goto done;
2732
0381101f
JH
2733 err = msglen;
2734
2735done:
2736 kfree(buf);
2737 return err;
2738}
c71e97bf 2739
b24752fe
JH
2740static void cmd_status_rsp(struct pending_cmd *cmd, void *data)
2741{
2742 u8 *status = data;
2743
2744 cmd_status(cmd->sk, cmd->index, cmd->opcode, *status);
2745 mgmt_pending_remove(cmd);
2746}
2747
744cf19e 2748int mgmt_index_added(struct hci_dev *hdev)
c71e97bf 2749{
744cf19e 2750 return mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL);
c71e97bf
JH
2751}
2752
744cf19e 2753int mgmt_index_removed(struct hci_dev *hdev)
c71e97bf 2754{
b24752fe
JH
2755 u8 status = ENODEV;
2756
744cf19e 2757 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
b24752fe 2758
744cf19e 2759 return mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL);
eec8d2bc
JH
2760}
2761
73f22f62 2762struct cmd_lookup {
eec8d2bc 2763 struct sock *sk;
69ab39ea 2764 struct hci_dev *hdev;
eec8d2bc
JH
2765};
2766
69ab39ea 2767static void settings_rsp(struct pending_cmd *cmd, void *data)
eec8d2bc 2768{
73f22f62 2769 struct cmd_lookup *match = data;
eec8d2bc 2770
69ab39ea 2771 send_settings_rsp(cmd->sk, cmd->opcode, match->hdev);
eec8d2bc
JH
2772
2773 list_del(&cmd->list);
2774
2775 if (match->sk == NULL) {
2776 match->sk = cmd->sk;
2777 sock_hold(match->sk);
2778 }
2779
2780 mgmt_pending_free(cmd);
c71e97bf 2781}
5add6af8 2782
744cf19e 2783int mgmt_powered(struct hci_dev *hdev, u8 powered)
5add6af8 2784{
76a7f3a4 2785 struct cmd_lookup match = { NULL, hdev };
69ab39ea 2786 __le32 ev;
7bb895d6 2787 int err;
5add6af8 2788
69ab39ea 2789 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
5add6af8 2790
b24752fe
JH
2791 if (!powered) {
2792 u8 status = ENETDOWN;
744cf19e 2793 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
b24752fe
JH
2794 }
2795
69ab39ea 2796 ev = cpu_to_le32(get_current_settings(hdev));
eec8d2bc 2797
7bb895d6 2798 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev),
69ab39ea 2799 match.sk);
eec8d2bc
JH
2800
2801 if (match.sk)
2802 sock_put(match.sk);
2803
7bb895d6 2804 return err;
5add6af8 2805}
73f22f62 2806
744cf19e 2807int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
73f22f62 2808{
76a7f3a4 2809 struct cmd_lookup match = { NULL, hdev };
69ab39ea 2810 __le32 ev;
7bb895d6 2811 int err;
73f22f62 2812
69ab39ea 2813 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, settings_rsp, &match);
72a734ec 2814
69ab39ea 2815 ev = cpu_to_le32(get_current_settings(hdev));
73f22f62 2816
7bb895d6 2817 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev),
4e51eae9 2818 match.sk);
73f22f62
JH
2819 if (match.sk)
2820 sock_put(match.sk);
2821
7bb895d6 2822 return err;
73f22f62 2823}
9fbcbb45 2824
744cf19e 2825int mgmt_connectable(struct hci_dev *hdev, u8 connectable)
9fbcbb45 2826{
69ab39ea 2827 __le32 ev;
76a7f3a4 2828 struct cmd_lookup match = { NULL, hdev };
7bb895d6 2829 int err;
9fbcbb45 2830
69ab39ea
JH
2831 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, settings_rsp,
2832 &match);
9fbcbb45 2833
69ab39ea 2834 ev = cpu_to_le32(get_current_settings(hdev));
9fbcbb45 2835
7bb895d6 2836 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), match.sk);
9fbcbb45
JH
2837
2838 if (match.sk)
2839 sock_put(match.sk);
2840
7bb895d6 2841 return err;
9fbcbb45 2842}
55ed8ca1 2843
744cf19e 2844int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status)
2d7cee58 2845{
ca69b795
JH
2846 u8 mgmt_err = mgmt_status(status);
2847
2d7cee58 2848 if (scan & SCAN_PAGE)
744cf19e 2849 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev,
ca69b795 2850 cmd_status_rsp, &mgmt_err);
2d7cee58
JH
2851
2852 if (scan & SCAN_INQUIRY)
744cf19e 2853 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev,
ca69b795 2854 cmd_status_rsp, &mgmt_err);
2d7cee58
JH
2855
2856 return 0;
2857}
2858
744cf19e
JH
2859int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
2860 u8 persistent)
55ed8ca1 2861{
86742e1e 2862 struct mgmt_ev_new_link_key ev;
55ed8ca1 2863
a492cd52 2864 memset(&ev, 0, sizeof(ev));
55ed8ca1 2865
a492cd52 2866 ev.store_hint = persistent;
d753fdc4
JH
2867 bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
2868 ev.key.addr.type = MGMT_ADDR_BREDR;
a492cd52
VCG
2869 ev.key.type = key->type;
2870 memcpy(ev.key.val, key->val, 16);
2871 ev.key.pin_len = key->pin_len;
55ed8ca1 2872
744cf19e 2873 return mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL);
55ed8ca1 2874}
f7520543 2875
346af67b
VCG
2876int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent)
2877{
2878 struct mgmt_ev_new_long_term_key ev;
2879
2880 memset(&ev, 0, sizeof(ev));
2881
2882 ev.store_hint = persistent;
2883 bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
2884 ev.key.addr.type = key->bdaddr_type;
2885 ev.key.authenticated = key->authenticated;
2886 ev.key.enc_size = key->enc_size;
2887 ev.key.ediv = key->ediv;
2888
2889 if (key->type == HCI_SMP_LTK)
2890 ev.key.master = 1;
2891
2892 memcpy(ev.key.rand, key->rand, sizeof(key->rand));
2893 memcpy(ev.key.val, key->val, sizeof(key->val));
2894
2895 return mgmt_event(MGMT_EV_NEW_LONG_TERM_KEY, hdev,
2896 &ev, sizeof(ev), NULL);
2897}
2898
afc747a6 2899int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
b644ba33
JH
2900 u8 addr_type, u8 *name, u8 name_len,
2901 u8 *dev_class)
f7520543 2902{
b644ba33
JH
2903 char buf[512];
2904 struct mgmt_ev_device_connected *ev = (void *) buf;
2905 u16 eir_len = 0;
f7520543 2906
b644ba33
JH
2907 bacpy(&ev->addr.bdaddr, bdaddr);
2908 ev->addr.type = link_to_mgmt(link_type, addr_type);
f7520543 2909
b644ba33
JH
2910 if (name_len > 0)
2911 eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE,
2912 name, name_len);
2913
2914 if (dev_class && memcmp(dev_class, "\0\0\0", 3) != 0)
2915 eir_len = eir_append_data(&ev->eir[eir_len], eir_len,
2916 EIR_CLASS_OF_DEV, dev_class, 3);
2917
2918 put_unaligned_le16(eir_len, &ev->eir_len);
2919
2920 return mgmt_event(MGMT_EV_DEVICE_CONNECTED, hdev, buf,
2921 sizeof(*ev) + eir_len, NULL);
f7520543
JH
2922}
2923
8962ee74
JH
2924static void disconnect_rsp(struct pending_cmd *cmd, void *data)
2925{
c68fb7ff 2926 struct mgmt_cp_disconnect *cp = cmd->param;
8962ee74 2927 struct sock **sk = data;
a38528f1 2928 struct mgmt_rp_disconnect rp;
8962ee74 2929
88c3df13
JH
2930 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
2931 rp.addr.type = cp->addr.type;
8962ee74 2932
aee9b218
JH
2933 cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, 0, &rp,
2934 sizeof(rp));
8962ee74
JH
2935
2936 *sk = cmd->sk;
2937 sock_hold(*sk);
2938
a664b5bc 2939 mgmt_pending_remove(cmd);
8962ee74
JH
2940}
2941
124f6e35 2942static void unpair_device_rsp(struct pending_cmd *cmd, void *data)
a8a1d19e 2943{
b1078ad0 2944 struct hci_dev *hdev = data;
124f6e35
JH
2945 struct mgmt_cp_unpair_device *cp = cmd->param;
2946 struct mgmt_rp_unpair_device rp;
a8a1d19e
JH
2947
2948 memset(&rp, 0, sizeof(rp));
124f6e35
JH
2949 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
2950 rp.addr.type = cp->addr.type;
a8a1d19e 2951
b1078ad0
JH
2952 device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, cmd->sk);
2953
aee9b218 2954 cmd_complete(cmd->sk, cmd->index, cmd->opcode, 0, &rp, sizeof(rp));
a8a1d19e
JH
2955
2956 mgmt_pending_remove(cmd);
2957}
2958
afc747a6
JH
2959int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
2960 u8 link_type, u8 addr_type)
f7520543 2961{
4c659c39 2962 struct mgmt_addr_info ev;
8962ee74
JH
2963 struct sock *sk = NULL;
2964 int err;
2965
744cf19e 2966 mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk);
f7520543 2967
f7520543 2968 bacpy(&ev.bdaddr, bdaddr);
48264f06 2969 ev.type = link_to_mgmt(link_type, addr_type);
f7520543 2970
afc747a6
JH
2971 err = mgmt_event(MGMT_EV_DEVICE_DISCONNECTED, hdev, &ev, sizeof(ev),
2972 sk);
8962ee74
JH
2973
2974 if (sk)
2975 sock_put(sk);
2976
124f6e35 2977 mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp,
b1078ad0 2978 hdev);
a8a1d19e 2979
8962ee74
JH
2980 return err;
2981}
2982
88c3df13
JH
2983int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
2984 u8 link_type, u8 addr_type, u8 status)
8962ee74 2985{
88c3df13 2986 struct mgmt_rp_disconnect rp;
8962ee74
JH
2987 struct pending_cmd *cmd;
2988 int err;
2989
2e58ef3e 2990 cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev);
8962ee74
JH
2991 if (!cmd)
2992 return -ENOENT;
2993
88c3df13
JH
2994 bacpy(&rp.addr.bdaddr, bdaddr);
2995 rp.addr.type = link_to_mgmt(link_type, addr_type);
37d9ef76 2996
88c3df13 2997 err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT,
aee9b218 2998 mgmt_status(status), &rp, sizeof(rp));
8962ee74 2999
a664b5bc 3000 mgmt_pending_remove(cmd);
8962ee74 3001
b1078ad0
JH
3002 mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp,
3003 hdev);
8962ee74 3004 return err;
f7520543 3005}
17d5c04c 3006
48264f06
JH
3007int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
3008 u8 addr_type, u8 status)
17d5c04c
JH
3009{
3010 struct mgmt_ev_connect_failed ev;
3011
4c659c39 3012 bacpy(&ev.addr.bdaddr, bdaddr);
48264f06 3013 ev.addr.type = link_to_mgmt(link_type, addr_type);
ca69b795 3014 ev.status = mgmt_status(status);
17d5c04c 3015
744cf19e 3016 return mgmt_event(MGMT_EV_CONNECT_FAILED, hdev, &ev, sizeof(ev), NULL);
17d5c04c 3017}
980e1a53 3018
744cf19e 3019int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure)
980e1a53
JH
3020{
3021 struct mgmt_ev_pin_code_request ev;
3022
d8457698
JH
3023 bacpy(&ev.addr.bdaddr, bdaddr);
3024 ev.addr.type = MGMT_ADDR_BREDR;
a770bb5a 3025 ev.secure = secure;
980e1a53 3026
744cf19e 3027 return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, hdev, &ev, sizeof(ev),
4e51eae9 3028 NULL);
980e1a53
JH
3029}
3030
744cf19e
JH
3031int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
3032 u8 status)
980e1a53
JH
3033{
3034 struct pending_cmd *cmd;
ac56fb13 3035 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
3036 int err;
3037
2e58ef3e 3038 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev);
980e1a53
JH
3039 if (!cmd)
3040 return -ENOENT;
3041
d8457698
JH
3042 bacpy(&rp.addr.bdaddr, bdaddr);
3043 rp.addr.type = MGMT_ADDR_BREDR;
ac56fb13 3044
aee9b218
JH
3045 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_REPLY,
3046 mgmt_status(status), &rp, sizeof(rp));
980e1a53 3047
a664b5bc 3048 mgmt_pending_remove(cmd);
980e1a53
JH
3049
3050 return err;
3051}
3052
744cf19e
JH
3053int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
3054 u8 status)
980e1a53
JH
3055{
3056 struct pending_cmd *cmd;
ac56fb13 3057 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
3058 int err;
3059
2e58ef3e 3060 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev);
980e1a53
JH
3061 if (!cmd)
3062 return -ENOENT;
3063
d8457698
JH
3064 bacpy(&rp.addr.bdaddr, bdaddr);
3065 rp.addr.type = MGMT_ADDR_BREDR;
ac56fb13 3066
aee9b218
JH
3067 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY,
3068 mgmt_status(status), &rp, sizeof(rp));
980e1a53 3069
a664b5bc 3070 mgmt_pending_remove(cmd);
980e1a53
JH
3071
3072 return err;
3073}
a5c29683 3074
744cf19e 3075int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
272d90df
JH
3076 u8 link_type, u8 addr_type, __le32 value,
3077 u8 confirm_hint)
a5c29683
JH
3078{
3079 struct mgmt_ev_user_confirm_request ev;
3080
744cf19e 3081 BT_DBG("%s", hdev->name);
a5c29683 3082
272d90df
JH
3083 bacpy(&ev.addr.bdaddr, bdaddr);
3084 ev.addr.type = link_to_mgmt(link_type, addr_type);
55bc1a37 3085 ev.confirm_hint = confirm_hint;
a5c29683
JH
3086 put_unaligned_le32(value, &ev.value);
3087
744cf19e 3088 return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, hdev, &ev, sizeof(ev),
4e51eae9 3089 NULL);
a5c29683
JH
3090}
3091
272d90df
JH
3092int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
3093 u8 link_type, u8 addr_type)
604086b7
BG
3094{
3095 struct mgmt_ev_user_passkey_request ev;
3096
3097 BT_DBG("%s", hdev->name);
3098
272d90df
JH
3099 bacpy(&ev.addr.bdaddr, bdaddr);
3100 ev.addr.type = link_to_mgmt(link_type, addr_type);
604086b7
BG
3101
3102 return mgmt_event(MGMT_EV_USER_PASSKEY_REQUEST, hdev, &ev, sizeof(ev),
3103 NULL);
3104}
3105
0df4c185 3106static int user_pairing_resp_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
272d90df
JH
3107 u8 link_type, u8 addr_type, u8 status,
3108 u8 opcode)
a5c29683
JH
3109{
3110 struct pending_cmd *cmd;
3111 struct mgmt_rp_user_confirm_reply rp;
3112 int err;
3113
2e58ef3e 3114 cmd = mgmt_pending_find(opcode, hdev);
a5c29683
JH
3115 if (!cmd)
3116 return -ENOENT;
3117
272d90df
JH
3118 bacpy(&rp.addr.bdaddr, bdaddr);
3119 rp.addr.type = link_to_mgmt(link_type, addr_type);
aee9b218
JH
3120 err = cmd_complete(cmd->sk, hdev->id, opcode, mgmt_status(status),
3121 &rp, sizeof(rp));
a5c29683 3122
a664b5bc 3123 mgmt_pending_remove(cmd);
a5c29683
JH
3124
3125 return err;
3126}
3127
744cf19e 3128int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
272d90df 3129 u8 link_type, u8 addr_type, u8 status)
a5c29683 3130{
272d90df
JH
3131 return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type,
3132 status, MGMT_OP_USER_CONFIRM_REPLY);
a5c29683
JH
3133}
3134
272d90df
JH
3135int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
3136 u8 link_type, u8 addr_type, u8 status)
a5c29683 3137{
272d90df
JH
3138 return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type,
3139 status, MGMT_OP_USER_CONFIRM_NEG_REPLY);
a5c29683 3140}
2a611692 3141
604086b7 3142int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
272d90df 3143 u8 link_type, u8 addr_type, u8 status)
604086b7 3144{
272d90df
JH
3145 return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type,
3146 status, MGMT_OP_USER_PASSKEY_REPLY);
604086b7
BG
3147}
3148
272d90df
JH
3149int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
3150 u8 link_type, u8 addr_type, u8 status)
604086b7 3151{
272d90df
JH
3152 return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type,
3153 status, MGMT_OP_USER_PASSKEY_NEG_REPLY);
604086b7
BG
3154}
3155
bab73cb6
JH
3156int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
3157 u8 addr_type, u8 status)
2a611692
JH
3158{
3159 struct mgmt_ev_auth_failed ev;
3160
bab73cb6
JH
3161 bacpy(&ev.addr.bdaddr, bdaddr);
3162 ev.addr.type = link_to_mgmt(link_type, addr_type);
ca69b795 3163 ev.status = mgmt_status(status);
2a611692 3164
744cf19e 3165 return mgmt_event(MGMT_EV_AUTH_FAILED, hdev, &ev, sizeof(ev), NULL);
2a611692 3166}
b312b161 3167
33ef95ed
JH
3168int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
3169{
3170 struct cmd_lookup match = { NULL, hdev };
3171 __le32 ev;
3172 int err;
3173
3174 if (status) {
3175 u8 mgmt_err = mgmt_status(status);
3176 mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev,
3177 cmd_status_rsp, &mgmt_err);
3178 return 0;
3179 }
3180
3181 mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp,
3182 &match);
3183
3184 ev = cpu_to_le32(get_current_settings(hdev));
3185 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), match.sk);
3186
3187 if (match.sk)
3188 sock_put(match.sk);
3189
3190 return err;
3191}
3192
ed2c4ee3
JH
3193int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 status)
3194{
3195 struct cmd_lookup match = { NULL, hdev };
3196 __le32 ev;
3197 int err;
3198
3199 if (status) {
3200 u8 mgmt_err = mgmt_status(status);
3201 mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev,
3202 cmd_status_rsp, &mgmt_err);
3203 return 0;
3204 }
3205
3206 mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match);
3207
3208 ev = cpu_to_le32(get_current_settings(hdev));
3209 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), match.sk);
3210
3211 if (match.sk)
3212 sock_put(match.sk);
3213
3214 return err;
3215}
3216
744cf19e 3217int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status)
b312b161
JH
3218{
3219 struct pending_cmd *cmd;
3220 struct mgmt_cp_set_local_name ev;
3221 int err;
3222
3223 memset(&ev, 0, sizeof(ev));
3224 memcpy(ev.name, name, HCI_MAX_NAME_LENGTH);
3225
2e58ef3e 3226 cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev);
b312b161
JH
3227 if (!cmd)
3228 goto send_event;
3229
3230 if (status) {
744cf19e 3231 err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
ca69b795 3232 mgmt_status(status));
b312b161
JH
3233 goto failed;
3234 }
3235
744cf19e 3236 update_eir(hdev);
80a1e1db 3237
aee9b218 3238 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0, &ev,
b312b161
JH
3239 sizeof(ev));
3240 if (err < 0)
3241 goto failed;
3242
3243send_event:
744cf19e 3244 err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev),
b312b161
JH
3245 cmd ? cmd->sk : NULL);
3246
3247failed:
3248 if (cmd)
3249 mgmt_pending_remove(cmd);
3250 return err;
3251}
c35938b2 3252
744cf19e
JH
3253int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
3254 u8 *randomizer, u8 status)
c35938b2
SJ
3255{
3256 struct pending_cmd *cmd;
3257 int err;
3258
744cf19e 3259 BT_DBG("%s status %u", hdev->name, status);
c35938b2 3260
2e58ef3e 3261 cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev);
c35938b2
SJ
3262 if (!cmd)
3263 return -ENOENT;
3264
3265 if (status) {
744cf19e 3266 err = cmd_status(cmd->sk, hdev->id,
ca69b795
JH
3267 MGMT_OP_READ_LOCAL_OOB_DATA,
3268 mgmt_status(status));
c35938b2
SJ
3269 } else {
3270 struct mgmt_rp_read_local_oob_data rp;
3271
3272 memcpy(rp.hash, hash, sizeof(rp.hash));
3273 memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer));
3274
744cf19e
JH
3275 err = cmd_complete(cmd->sk, hdev->id,
3276 MGMT_OP_READ_LOCAL_OOB_DATA,
aee9b218 3277 0, &rp, sizeof(rp));
c35938b2
SJ
3278 }
3279
3280 mgmt_pending_remove(cmd);
3281
3282 return err;
3283}
e17acd40 3284
48264f06 3285int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
561aafbc 3286 u8 addr_type, u8 *dev_class, s8 rssi,
e319d2e7 3287 u8 cfm_name, u8 *eir, u16 eir_len)
e17acd40 3288{
e319d2e7
JH
3289 char buf[512];
3290 struct mgmt_ev_device_found *ev = (void *) buf;
1dc06093 3291 size_t ev_size;
e17acd40 3292
1dc06093
JH
3293 /* Leave 5 bytes for a potential CoD field */
3294 if (sizeof(*ev) + eir_len + 5 > sizeof(buf))
7d262f86
AG
3295 return -EINVAL;
3296
1dc06093
JH
3297 memset(buf, 0, sizeof(buf));
3298
e319d2e7
JH
3299 bacpy(&ev->addr.bdaddr, bdaddr);
3300 ev->addr.type = link_to_mgmt(link_type, addr_type);
3301 ev->rssi = rssi;
3302 ev->confirm_name = cfm_name;
e17acd40 3303
1dc06093 3304 if (eir_len > 0)
e319d2e7 3305 memcpy(ev->eir, eir, eir_len);
e17acd40 3306
1dc06093
JH
3307 if (dev_class && !eir_has_data_type(ev->eir, eir_len, EIR_CLASS_OF_DEV))
3308 eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV,
3309 dev_class, 3);
3310
3311 put_unaligned_le16(eir_len, &ev->eir_len);
3312
3313 ev_size = sizeof(*ev) + eir_len;
f8523598 3314
e319d2e7 3315 return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL);
e17acd40 3316}
a88a9652 3317
b644ba33
JH
3318int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
3319 u8 addr_type, s8 rssi, u8 *name, u8 name_len)
a88a9652 3320{
b644ba33
JH
3321 struct mgmt_ev_device_found *ev;
3322 char buf[sizeof(*ev) + HCI_MAX_NAME_LENGTH + 2];
3323 u16 eir_len;
a88a9652 3324
b644ba33 3325 ev = (struct mgmt_ev_device_found *) buf;
a88a9652 3326
b644ba33
JH
3327 memset(buf, 0, sizeof(buf));
3328
3329 bacpy(&ev->addr.bdaddr, bdaddr);
3330 ev->addr.type = link_to_mgmt(link_type, addr_type);
3331 ev->rssi = rssi;
3332
3333 eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, name,
3334 name_len);
3335
3336 put_unaligned_le16(eir_len, &ev->eir_len);
a88a9652 3337
053c7e0c
JH
3338 return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev,
3339 sizeof(*ev) + eir_len, NULL);
a88a9652 3340}
314b2381 3341
7a135109 3342int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status)
164a6e78
JH
3343{
3344 struct pending_cmd *cmd;
f808e166 3345 u8 type;
164a6e78
JH
3346 int err;
3347
203159d4
AG
3348 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
3349
2e58ef3e 3350 cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev);
164a6e78
JH
3351 if (!cmd)
3352 return -ENOENT;
3353
f808e166
JH
3354 type = hdev->discovery.type;
3355
3356 err = cmd_complete(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status),
3357 &type, sizeof(type));
164a6e78
JH
3358 mgmt_pending_remove(cmd);
3359
3360 return err;
3361}
3362
e6d465cb
AG
3363int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status)
3364{
3365 struct pending_cmd *cmd;
3366 int err;
3367
3368 cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev);
3369 if (!cmd)
3370 return -ENOENT;
3371
e75a8b0c 3372 err = cmd_status(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status));
164a6e78
JH
3373 mgmt_pending_remove(cmd);
3374
3375 return err;
3376}
3377
744cf19e 3378int mgmt_discovering(struct hci_dev *hdev, u8 discovering)
314b2381 3379{
164a6e78
JH
3380 struct pending_cmd *cmd;
3381
343fb145
AG
3382 BT_DBG("%s discovering %u", hdev->name, discovering);
3383
164a6e78 3384 if (discovering)
2e58ef3e 3385 cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev);
164a6e78 3386 else
2e58ef3e 3387 cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev);
164a6e78
JH
3388
3389 if (cmd != NULL) {
f808e166
JH
3390 u8 type = hdev->discovery.type;
3391
3392 if (discovering)
3393 cmd_complete(cmd->sk, hdev->id, cmd->opcode, 0,
3394 &type, sizeof(type));
3395 else
3396 cmd_complete(cmd->sk, hdev->id, cmd->opcode, 0,
3397 NULL, 0);
164a6e78
JH
3398 mgmt_pending_remove(cmd);
3399 }
3400
744cf19e 3401 return mgmt_event(MGMT_EV_DISCOVERING, hdev, &discovering,
314b2381
JH
3402 sizeof(discovering), NULL);
3403}
5e762444 3404
88c1fe4b 3405int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
5e762444
AJ
3406{
3407 struct pending_cmd *cmd;
3408 struct mgmt_ev_device_blocked ev;
3409
2e58ef3e 3410 cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, hdev);
5e762444 3411
88c1fe4b
JH
3412 bacpy(&ev.addr.bdaddr, bdaddr);
3413 ev.addr.type = type;
5e762444 3414
744cf19e
JH
3415 return mgmt_event(MGMT_EV_DEVICE_BLOCKED, hdev, &ev, sizeof(ev),
3416 cmd ? cmd->sk : NULL);
5e762444
AJ
3417}
3418
88c1fe4b 3419int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
5e762444
AJ
3420{
3421 struct pending_cmd *cmd;
3422 struct mgmt_ev_device_unblocked ev;
3423
2e58ef3e 3424 cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, hdev);
5e762444 3425
88c1fe4b
JH
3426 bacpy(&ev.addr.bdaddr, bdaddr);
3427 ev.addr.type = type;
5e762444 3428
744cf19e
JH
3429 return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &ev, sizeof(ev),
3430 cmd ? cmd->sk : NULL);
5e762444 3431}
d7b7e796
MH
3432
3433module_param(enable_hs, bool, 0644);
3434MODULE_PARM_DESC(enable_hs, "Enable High Speed support");
3435
3436module_param(enable_le, bool, 0644);
3437MODULE_PARM_DESC(enable_le, "Enable Low Energy support");
This page took 0.297094 seconds and 5 git commands to generate.