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