Bluetooth: mgmt: Add address type to link key 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
1531 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(cp->bdaddr),
1532 &cp->bdaddr);
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;
96d97a67 1544 struct mgmt_cp_pin_code_neg_reply ncp;
980e1a53 1545 struct hci_cp_pin_code_reply reply;
366a0336 1546 struct pending_cmd *cmd;
980e1a53
JH
1547 int err;
1548
1549 BT_DBG("");
1550
bdce7baf 1551 if (len != sizeof(*cp))
ca69b795
JH
1552 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1553 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1554
4e51eae9 1555 hdev = hci_dev_get(index);
980e1a53 1556 if (!hdev)
ca69b795
JH
1557 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1558 MGMT_STATUS_INVALID_PARAMS);
980e1a53 1559
09fd0de5 1560 hci_dev_lock(hdev);
980e1a53
JH
1561
1562 if (!test_bit(HCI_UP, &hdev->flags)) {
ca69b795
JH
1563 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1564 MGMT_STATUS_NOT_POWERED);
980e1a53
JH
1565 goto failed;
1566 }
1567
96d97a67
WR
1568 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1569 if (!conn) {
ca69b795
JH
1570 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1571 MGMT_STATUS_NOT_CONNECTED);
96d97a67
WR
1572 goto failed;
1573 }
1574
1575 if (conn->pending_sec_level == BT_SECURITY_HIGH && cp->pin_len != 16) {
1576 bacpy(&ncp.bdaddr, &cp->bdaddr);
1577
1578 BT_ERR("PIN code is not 16 bytes long");
1579
1580 err = send_pin_code_neg_reply(sk, index, hdev, &ncp);
1581 if (err >= 0)
1582 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
ca69b795 1583 MGMT_STATUS_INVALID_PARAMS);
96d97a67
WR
1584
1585 goto failed;
1586 }
1587
650f726d
VCG
1588 cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, hdev, data,
1589 len);
366a0336
JH
1590 if (!cmd) {
1591 err = -ENOMEM;
980e1a53 1592 goto failed;
366a0336 1593 }
980e1a53
JH
1594
1595 bacpy(&reply.bdaddr, &cp->bdaddr);
1596 reply.pin_len = cp->pin_len;
24718ca5 1597 memcpy(reply.pin_code, cp->pin_code, sizeof(reply.pin_code));
980e1a53
JH
1598
1599 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_REPLY, sizeof(reply), &reply);
1600 if (err < 0)
a664b5bc 1601 mgmt_pending_remove(cmd);
980e1a53
JH
1602
1603failed:
09fd0de5 1604 hci_dev_unlock(hdev);
980e1a53
JH
1605 hci_dev_put(hdev);
1606
1607 return err;
1608}
1609
650f726d 1610static int pin_code_neg_reply(struct sock *sk, u16 index, void *data, u16 len)
980e1a53
JH
1611{
1612 struct hci_dev *hdev;
650f726d 1613 struct mgmt_cp_pin_code_neg_reply *cp = data;
980e1a53
JH
1614 int err;
1615
1616 BT_DBG("");
1617
bdce7baf
SJ
1618 if (len != sizeof(*cp))
1619 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
ca69b795 1620 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1621
4e51eae9 1622 hdev = hci_dev_get(index);
980e1a53 1623 if (!hdev)
4e51eae9 1624 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
ca69b795 1625 MGMT_STATUS_INVALID_PARAMS);
980e1a53 1626
09fd0de5 1627 hci_dev_lock(hdev);
980e1a53
JH
1628
1629 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9 1630 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
ca69b795 1631 MGMT_STATUS_NOT_POWERED);
980e1a53
JH
1632 goto failed;
1633 }
1634
96d97a67 1635 err = send_pin_code_neg_reply(sk, index, hdev, cp);
980e1a53
JH
1636
1637failed:
09fd0de5 1638 hci_dev_unlock(hdev);
980e1a53
JH
1639 hci_dev_put(hdev);
1640
1641 return err;
1642}
1643
650f726d 1644static int set_io_capability(struct sock *sk, u16 index, void *data, u16 len)
17fa4b9d
JH
1645{
1646 struct hci_dev *hdev;
650f726d 1647 struct mgmt_cp_set_io_capability *cp = data;
17fa4b9d
JH
1648
1649 BT_DBG("");
1650
bdce7baf 1651 if (len != sizeof(*cp))
ca69b795
JH
1652 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY,
1653 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1654
4e51eae9 1655 hdev = hci_dev_get(index);
17fa4b9d 1656 if (!hdev)
ca69b795
JH
1657 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY,
1658 MGMT_STATUS_INVALID_PARAMS);
17fa4b9d 1659
09fd0de5 1660 hci_dev_lock(hdev);
17fa4b9d
JH
1661
1662 hdev->io_capability = cp->io_capability;
1663
1664 BT_DBG("%s IO capability set to 0x%02x", hdev->name,
b8534e0f 1665 hdev->io_capability);
17fa4b9d 1666
09fd0de5 1667 hci_dev_unlock(hdev);
17fa4b9d
JH
1668 hci_dev_put(hdev);
1669
4e51eae9 1670 return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, NULL, 0);
17fa4b9d
JH
1671}
1672
e9a416b5
JH
1673static inline struct pending_cmd *find_pairing(struct hci_conn *conn)
1674{
1675 struct hci_dev *hdev = conn->hdev;
8035ded4 1676 struct pending_cmd *cmd;
e9a416b5 1677
2e58ef3e 1678 list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
e9a416b5
JH
1679 if (cmd->opcode != MGMT_OP_PAIR_DEVICE)
1680 continue;
1681
e9a416b5
JH
1682 if (cmd->user_data != conn)
1683 continue;
1684
1685 return cmd;
1686 }
1687
1688 return NULL;
1689}
1690
1691static void pairing_complete(struct pending_cmd *cmd, u8 status)
1692{
1693 struct mgmt_rp_pair_device rp;
1694 struct hci_conn *conn = cmd->user_data;
1695
ba4e564f
JH
1696 bacpy(&rp.addr.bdaddr, &conn->dst);
1697 rp.addr.type = link_to_mgmt(conn->type, conn->dst_type);
e9a416b5
JH
1698 rp.status = status;
1699
4e51eae9 1700 cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, &rp, sizeof(rp));
e9a416b5
JH
1701
1702 /* So we don't get further callbacks for this connection */
1703 conn->connect_cfm_cb = NULL;
1704 conn->security_cfm_cb = NULL;
1705 conn->disconn_cfm_cb = NULL;
1706
1707 hci_conn_put(conn);
1708
a664b5bc 1709 mgmt_pending_remove(cmd);
e9a416b5
JH
1710}
1711
1712static void pairing_complete_cb(struct hci_conn *conn, u8 status)
1713{
1714 struct pending_cmd *cmd;
1715
1716 BT_DBG("status %u", status);
1717
1718 cmd = find_pairing(conn);
56e5cb86 1719 if (!cmd)
e9a416b5 1720 BT_DBG("Unable to find a pending command");
56e5cb86
JH
1721 else
1722 pairing_complete(cmd, status);
e9a416b5
JH
1723}
1724
650f726d 1725static int pair_device(struct sock *sk, u16 index, void *data, u16 len)
e9a416b5
JH
1726{
1727 struct hci_dev *hdev;
650f726d 1728 struct mgmt_cp_pair_device *cp = data;
1425acb7 1729 struct mgmt_rp_pair_device rp;
e9a416b5
JH
1730 struct pending_cmd *cmd;
1731 u8 sec_level, auth_type;
1732 struct hci_conn *conn;
e9a416b5
JH
1733 int err;
1734
1735 BT_DBG("");
1736
bdce7baf 1737 if (len != sizeof(*cp))
ca69b795
JH
1738 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE,
1739 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1740
4e51eae9 1741 hdev = hci_dev_get(index);
e9a416b5 1742 if (!hdev)
ca69b795
JH
1743 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE,
1744 MGMT_STATUS_INVALID_PARAMS);
e9a416b5 1745
09fd0de5 1746 hci_dev_lock(hdev);
e9a416b5 1747
c908df36
VCG
1748 sec_level = BT_SECURITY_MEDIUM;
1749 if (cp->io_cap == 0x03)
e9a416b5 1750 auth_type = HCI_AT_DEDICATED_BONDING;
c908df36 1751 else
e9a416b5 1752 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
e9a416b5 1753
ba4e564f
JH
1754 if (cp->addr.type == MGMT_ADDR_BREDR)
1755 conn = hci_connect(hdev, ACL_LINK, &cp->addr.bdaddr, sec_level,
7a512d01
VCG
1756 auth_type);
1757 else
ba4e564f 1758 conn = hci_connect(hdev, LE_LINK, &cp->addr.bdaddr, sec_level,
7a512d01
VCG
1759 auth_type);
1760
1425acb7
JH
1761 memset(&rp, 0, sizeof(rp));
1762 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
1763 rp.addr.type = cp->addr.type;
1764
30e76272 1765 if (IS_ERR(conn)) {
1425acb7
JH
1766 rp.status = -PTR_ERR(conn);
1767 err = cmd_complete(sk, index, MGMT_OP_PAIR_DEVICE,
1768 &rp, sizeof(rp));
e9a416b5
JH
1769 goto unlock;
1770 }
1771
1772 if (conn->connect_cfm_cb) {
1773 hci_conn_put(conn);
1425acb7
JH
1774 rp.status = EBUSY;
1775 err = cmd_complete(sk, index, MGMT_OP_PAIR_DEVICE,
1776 &rp, sizeof(rp));
e9a416b5
JH
1777 goto unlock;
1778 }
1779
2e58ef3e 1780 cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, hdev, data, len);
e9a416b5
JH
1781 if (!cmd) {
1782 err = -ENOMEM;
1783 hci_conn_put(conn);
1784 goto unlock;
1785 }
1786
7a512d01 1787 /* For LE, just connecting isn't a proof that the pairing finished */
ba4e564f 1788 if (cp->addr.type == MGMT_ADDR_BREDR)
7a512d01
VCG
1789 conn->connect_cfm_cb = pairing_complete_cb;
1790
e9a416b5
JH
1791 conn->security_cfm_cb = pairing_complete_cb;
1792 conn->disconn_cfm_cb = pairing_complete_cb;
1793 conn->io_capability = cp->io_cap;
1794 cmd->user_data = conn;
1795
1796 if (conn->state == BT_CONNECTED &&
1797 hci_conn_security(conn, sec_level, auth_type))
1798 pairing_complete(cmd, 0);
1799
1800 err = 0;
1801
1802unlock:
09fd0de5 1803 hci_dev_unlock(hdev);
e9a416b5
JH
1804 hci_dev_put(hdev);
1805
1806 return err;
1807}
1808
28424707
JH
1809static int cancel_pair_device(struct sock *sk, u16 index,
1810 unsigned char *data, u16 len)
1811{
1812 struct mgmt_addr_info *addr = (void *) data;
1813 struct hci_dev *hdev;
1814 struct pending_cmd *cmd;
1815 struct hci_conn *conn;
1816 int err;
1817
1818 BT_DBG("");
1819
1820 if (len != sizeof(*addr))
1821 return cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
1822 MGMT_STATUS_INVALID_PARAMS);
1823
1824 hdev = hci_dev_get(index);
1825 if (!hdev)
1826 return cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
1827 MGMT_STATUS_INVALID_PARAMS);
1828
1829 hci_dev_lock(hdev);
1830
1831 cmd = mgmt_pending_find(MGMT_OP_PAIR_DEVICE, hdev);
1832 if (!cmd) {
1833 err = cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
1834 MGMT_STATUS_INVALID_PARAMS);
1835 goto unlock;
1836 }
1837
1838 conn = cmd->user_data;
1839
1840 if (bacmp(&addr->bdaddr, &conn->dst) != 0) {
1841 err = cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
1842 MGMT_STATUS_INVALID_PARAMS);
1843 goto unlock;
1844 }
1845
1846 pairing_complete(cmd, MGMT_STATUS_CANCELLED);
1847
1848 err = cmd_complete(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE, addr,
1849 sizeof(*addr));
1850unlock:
1851 hci_dev_unlock(hdev);
1852 hci_dev_put(hdev);
1853
1854 return err;
1855}
1856
0df4c185 1857static int user_pairing_resp(struct sock *sk, u16 index, bdaddr_t *bdaddr,
272d90df
JH
1858 u8 type, u16 mgmt_op, u16 hci_op,
1859 __le32 passkey)
a5c29683 1860{
a5c29683
JH
1861 struct pending_cmd *cmd;
1862 struct hci_dev *hdev;
0df4c185 1863 struct hci_conn *conn;
a5c29683
JH
1864 int err;
1865
4e51eae9 1866 hdev = hci_dev_get(index);
a5c29683 1867 if (!hdev)
ca69b795
JH
1868 return cmd_status(sk, index, mgmt_op,
1869 MGMT_STATUS_INVALID_PARAMS);
a5c29683 1870
09fd0de5 1871 hci_dev_lock(hdev);
08ba5382 1872
a5c29683 1873 if (!test_bit(HCI_UP, &hdev->flags)) {
0df4c185
BG
1874 err = cmd_status(sk, index, mgmt_op, MGMT_STATUS_NOT_POWERED);
1875 goto done;
a5c29683
JH
1876 }
1877
272d90df
JH
1878 if (type == MGMT_ADDR_BREDR)
1879 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, bdaddr);
1880 else
47c15e2b 1881 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr);
272d90df
JH
1882
1883 if (!conn) {
1884 err = cmd_status(sk, index, mgmt_op,
47c15e2b 1885 MGMT_STATUS_NOT_CONNECTED);
272d90df
JH
1886 goto done;
1887 }
47c15e2b 1888
272d90df 1889 if (type == MGMT_ADDR_LE_PUBLIC || type == MGMT_ADDR_LE_RANDOM) {
47c15e2b 1890 /* Continue with pairing via SMP */
5fe57d9e
BG
1891 err = smp_user_confirm_reply(conn, mgmt_op, passkey);
1892
1893 if (!err)
1894 err = cmd_status(sk, index, mgmt_op,
1895 MGMT_STATUS_SUCCESS);
1896 else
1897 err = cmd_status(sk, index, mgmt_op,
1898 MGMT_STATUS_FAILED);
47c15e2b 1899
47c15e2b
BG
1900 goto done;
1901 }
1902
0df4c185 1903 cmd = mgmt_pending_add(sk, mgmt_op, hdev, bdaddr, sizeof(*bdaddr));
a5c29683
JH
1904 if (!cmd) {
1905 err = -ENOMEM;
0df4c185 1906 goto done;
a5c29683
JH
1907 }
1908
0df4c185 1909 /* Continue with pairing via HCI */
604086b7
BG
1910 if (hci_op == HCI_OP_USER_PASSKEY_REPLY) {
1911 struct hci_cp_user_passkey_reply cp;
1912
1913 bacpy(&cp.bdaddr, bdaddr);
1914 cp.passkey = passkey;
1915 err = hci_send_cmd(hdev, hci_op, sizeof(cp), &cp);
1916 } else
1917 err = hci_send_cmd(hdev, hci_op, sizeof(*bdaddr), bdaddr);
1918
a664b5bc
JH
1919 if (err < 0)
1920 mgmt_pending_remove(cmd);
a5c29683 1921
0df4c185 1922done:
09fd0de5 1923 hci_dev_unlock(hdev);
a5c29683
JH
1924 hci_dev_put(hdev);
1925
1926 return err;
1927}
1928
0df4c185
BG
1929static int user_confirm_reply(struct sock *sk, u16 index, void *data, u16 len)
1930{
650f726d 1931 struct mgmt_cp_user_confirm_reply *cp = data;
0df4c185
BG
1932
1933 BT_DBG("");
1934
1935 if (len != sizeof(*cp))
1936 return cmd_status(sk, index, MGMT_OP_USER_CONFIRM_REPLY,
1937 MGMT_STATUS_INVALID_PARAMS);
1938
272d90df
JH
1939 return user_pairing_resp(sk, index, &cp->addr.bdaddr, cp->addr.type,
1940 MGMT_OP_USER_CONFIRM_REPLY,
1941 HCI_OP_USER_CONFIRM_REPLY, 0);
0df4c185
BG
1942}
1943
1944static int user_confirm_neg_reply(struct sock *sk, u16 index, void *data,
1945 u16 len)
1946{
c9c2659f 1947 struct mgmt_cp_user_confirm_neg_reply *cp = data;
0df4c185
BG
1948
1949 BT_DBG("");
1950
1951 if (len != sizeof(*cp))
1952 return cmd_status(sk, index, MGMT_OP_USER_CONFIRM_NEG_REPLY,
1953 MGMT_STATUS_INVALID_PARAMS);
1954
272d90df
JH
1955 return user_pairing_resp(sk, index, &cp->addr.bdaddr, cp->addr.type,
1956 MGMT_OP_USER_CONFIRM_NEG_REPLY,
1957 HCI_OP_USER_CONFIRM_NEG_REPLY, 0);
0df4c185
BG
1958}
1959
604086b7
BG
1960static int user_passkey_reply(struct sock *sk, u16 index, void *data, u16 len)
1961{
650f726d 1962 struct mgmt_cp_user_passkey_reply *cp = data;
604086b7
BG
1963
1964 BT_DBG("");
1965
1966 if (len != sizeof(*cp))
1967 return cmd_status(sk, index, MGMT_OP_USER_PASSKEY_REPLY,
1968 EINVAL);
1969
272d90df
JH
1970 return user_pairing_resp(sk, index, &cp->addr.bdaddr, cp->addr.type,
1971 MGMT_OP_USER_PASSKEY_REPLY,
1972 HCI_OP_USER_PASSKEY_REPLY,
1973 cp->passkey);
604086b7
BG
1974}
1975
1976static int user_passkey_neg_reply(struct sock *sk, u16 index, void *data,
1977 u16 len)
1978{
650f726d 1979 struct mgmt_cp_user_passkey_neg_reply *cp = data;
604086b7
BG
1980
1981 BT_DBG("");
1982
1983 if (len != sizeof(*cp))
1984 return cmd_status(sk, index, MGMT_OP_USER_PASSKEY_NEG_REPLY,
1985 EINVAL);
1986
272d90df
JH
1987 return user_pairing_resp(sk, index, &cp->addr.bdaddr, cp->addr.type,
1988 MGMT_OP_USER_PASSKEY_NEG_REPLY,
1989 HCI_OP_USER_PASSKEY_NEG_REPLY, 0);
604086b7
BG
1990}
1991
650f726d 1992static int set_local_name(struct sock *sk, u16 index, void *data,
b312b161
JH
1993 u16 len)
1994{
650f726d 1995 struct mgmt_cp_set_local_name *mgmt_cp = data;
b312b161
JH
1996 struct hci_cp_write_local_name hci_cp;
1997 struct hci_dev *hdev;
1998 struct pending_cmd *cmd;
1999 int err;
2000
2001 BT_DBG("");
2002
2003 if (len != sizeof(*mgmt_cp))
ca69b795
JH
2004 return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME,
2005 MGMT_STATUS_INVALID_PARAMS);
b312b161
JH
2006
2007 hdev = hci_dev_get(index);
2008 if (!hdev)
ca69b795
JH
2009 return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME,
2010 MGMT_STATUS_INVALID_PARAMS);
b312b161 2011
09fd0de5 2012 hci_dev_lock(hdev);
b312b161 2013
650f726d
VCG
2014 cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, hdev, data,
2015 len);
b312b161
JH
2016 if (!cmd) {
2017 err = -ENOMEM;
2018 goto failed;
2019 }
2020
2021 memcpy(hci_cp.name, mgmt_cp->name, sizeof(hci_cp.name));
2022 err = hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(hci_cp),
2023 &hci_cp);
2024 if (err < 0)
2025 mgmt_pending_remove(cmd);
2026
2027failed:
09fd0de5 2028 hci_dev_unlock(hdev);
b312b161
JH
2029 hci_dev_put(hdev);
2030
2031 return err;
2032}
2033
c35938b2
SJ
2034static int read_local_oob_data(struct sock *sk, u16 index)
2035{
2036 struct hci_dev *hdev;
2037 struct pending_cmd *cmd;
2038 int err;
2039
2040 BT_DBG("hci%u", index);
2041
2042 hdev = hci_dev_get(index);
2043 if (!hdev)
2044 return cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
ca69b795 2045 MGMT_STATUS_INVALID_PARAMS);
c35938b2 2046
09fd0de5 2047 hci_dev_lock(hdev);
c35938b2
SJ
2048
2049 if (!test_bit(HCI_UP, &hdev->flags)) {
2050 err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
ca69b795 2051 MGMT_STATUS_NOT_POWERED);
c35938b2
SJ
2052 goto unlock;
2053 }
2054
2055 if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) {
2056 err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
ca69b795 2057 MGMT_STATUS_NOT_SUPPORTED);
c35938b2
SJ
2058 goto unlock;
2059 }
2060
2e58ef3e 2061 if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev)) {
ca69b795
JH
2062 err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
2063 MGMT_STATUS_BUSY);
c35938b2
SJ
2064 goto unlock;
2065 }
2066
2e58ef3e 2067 cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, hdev, NULL, 0);
c35938b2
SJ
2068 if (!cmd) {
2069 err = -ENOMEM;
2070 goto unlock;
2071 }
2072
2073 err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
2074 if (err < 0)
2075 mgmt_pending_remove(cmd);
2076
2077unlock:
09fd0de5 2078 hci_dev_unlock(hdev);
c35938b2
SJ
2079 hci_dev_put(hdev);
2080
2081 return err;
2082}
2083
650f726d
VCG
2084static int add_remote_oob_data(struct sock *sk, u16 index, void *data,
2085 u16 len)
2763eda6
SJ
2086{
2087 struct hci_dev *hdev;
650f726d 2088 struct mgmt_cp_add_remote_oob_data *cp = data;
2763eda6
SJ
2089 int err;
2090
2091 BT_DBG("hci%u ", index);
2092
2093 if (len != sizeof(*cp))
2094 return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
ca69b795 2095 MGMT_STATUS_INVALID_PARAMS);
2763eda6
SJ
2096
2097 hdev = hci_dev_get(index);
2098 if (!hdev)
2099 return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
ca69b795 2100 MGMT_STATUS_INVALID_PARAMS);
2763eda6 2101
09fd0de5 2102 hci_dev_lock(hdev);
2763eda6 2103
664ce4cc 2104 err = hci_add_remote_oob_data(hdev, &cp->addr.bdaddr, cp->hash,
2763eda6
SJ
2105 cp->randomizer);
2106 if (err < 0)
ca69b795
JH
2107 err = cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
2108 MGMT_STATUS_FAILED);
2763eda6
SJ
2109 else
2110 err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, NULL,
2111 0);
2112
09fd0de5 2113 hci_dev_unlock(hdev);
2763eda6
SJ
2114 hci_dev_put(hdev);
2115
2116 return err;
2117}
2118
2119static int remove_remote_oob_data(struct sock *sk, u16 index,
650f726d 2120 void *data, u16 len)
2763eda6
SJ
2121{
2122 struct hci_dev *hdev;
650f726d 2123 struct mgmt_cp_remove_remote_oob_data *cp = data;
2763eda6
SJ
2124 int err;
2125
2126 BT_DBG("hci%u ", index);
2127
2128 if (len != sizeof(*cp))
2129 return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
ca69b795 2130 MGMT_STATUS_INVALID_PARAMS);
2763eda6
SJ
2131
2132 hdev = hci_dev_get(index);
2133 if (!hdev)
2134 return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
ca69b795 2135 MGMT_STATUS_INVALID_PARAMS);
2763eda6 2136
09fd0de5 2137 hci_dev_lock(hdev);
2763eda6 2138
664ce4cc 2139 err = hci_remove_remote_oob_data(hdev, &cp->addr.bdaddr);
2763eda6
SJ
2140 if (err < 0)
2141 err = cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
ca69b795 2142 MGMT_STATUS_INVALID_PARAMS);
2763eda6
SJ
2143 else
2144 err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
2145 NULL, 0);
2146
09fd0de5 2147 hci_dev_unlock(hdev);
2763eda6
SJ
2148 hci_dev_put(hdev);
2149
2150 return err;
2151}
2152
450dfdaf 2153static int start_discovery(struct sock *sk, u16 index,
650f726d 2154 void *data, u16 len)
14a53664 2155{
650f726d 2156 struct mgmt_cp_start_discovery *cp = data;
3fd24153 2157 unsigned long discov_type = cp->type;
14a53664
JH
2158 struct pending_cmd *cmd;
2159 struct hci_dev *hdev;
2160 int err;
2161
2162 BT_DBG("hci%u", index);
2163
450dfdaf
JH
2164 if (len != sizeof(*cp))
2165 return cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
2166 MGMT_STATUS_INVALID_PARAMS);
2167
14a53664
JH
2168 hdev = hci_dev_get(index);
2169 if (!hdev)
ca69b795
JH
2170 return cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
2171 MGMT_STATUS_INVALID_PARAMS);
14a53664 2172
09fd0de5 2173 hci_dev_lock(hdev);
14a53664 2174
bd2d1334 2175 if (!test_bit(HCI_UP, &hdev->flags)) {
ca69b795
JH
2176 err = cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
2177 MGMT_STATUS_NOT_POWERED);
bd2d1334
JH
2178 goto failed;
2179 }
2180
ff9ef578
JH
2181 if (hdev->discovery.state != DISCOVERY_STOPPED) {
2182 err = cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
2183 MGMT_STATUS_BUSY);
2184 goto failed;
2185 }
2186
2e58ef3e 2187 cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, hdev, NULL, 0);
14a53664
JH
2188 if (!cmd) {
2189 err = -ENOMEM;
2190 goto failed;
2191 }
2192
3fd24153
AG
2193 if (test_bit(MGMT_ADDR_BREDR, &discov_type))
2194 err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR);
2195 else if (test_bit(MGMT_ADDR_LE_PUBLIC, &discov_type) &&
2196 test_bit(MGMT_ADDR_LE_RANDOM, &discov_type))
2197 err = hci_le_scan(hdev, LE_SCAN_TYPE, LE_SCAN_INT,
2198 LE_SCAN_WIN, LE_SCAN_TIMEOUT_LE_ONLY);
2199 else
2200 err = -EINVAL;
2201
14a53664
JH
2202 if (err < 0)
2203 mgmt_pending_remove(cmd);
ff9ef578
JH
2204 else
2205 hci_discovery_set_state(hdev, DISCOVERY_STARTING);
14a53664
JH
2206
2207failed:
09fd0de5 2208 hci_dev_unlock(hdev);
14a53664
JH
2209 hci_dev_put(hdev);
2210
2211 return err;
2212}
2213
2214static int stop_discovery(struct sock *sk, u16 index)
2215{
2216 struct hci_dev *hdev;
2217 struct pending_cmd *cmd;
30dc78e1
JH
2218 struct hci_cp_remote_name_req_cancel cp;
2219 struct inquiry_entry *e;
14a53664
JH
2220 int err;
2221
2222 BT_DBG("hci%u", index);
2223
2224 hdev = hci_dev_get(index);
2225 if (!hdev)
ca69b795
JH
2226 return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY,
2227 MGMT_STATUS_INVALID_PARAMS);
14a53664 2228
09fd0de5 2229 hci_dev_lock(hdev);
14a53664 2230
30dc78e1 2231 if (!hci_discovery_active(hdev)) {
ff9ef578
JH
2232 err = cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY,
2233 MGMT_STATUS_REJECTED);
30dc78e1 2234 goto unlock;
ff9ef578
JH
2235 }
2236
2e58ef3e 2237 cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, NULL, 0);
14a53664
JH
2238 if (!cmd) {
2239 err = -ENOMEM;
30dc78e1
JH
2240 goto unlock;
2241 }
2242
2243 if (hdev->discovery.state == DISCOVERY_INQUIRY) {
2244 err = hci_cancel_inquiry(hdev);
2245 if (err < 0)
2246 mgmt_pending_remove(cmd);
2247 else
2248 hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
2249 goto unlock;
2250 }
2251
2252 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_PENDING);
2253 if (!e) {
2254 mgmt_pending_remove(cmd);
2255 err = cmd_complete(sk, index, MGMT_OP_STOP_DISCOVERY, NULL, 0);
2256 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
2257 goto unlock;
14a53664
JH
2258 }
2259
30dc78e1
JH
2260 bacpy(&cp.bdaddr, &e->data.bdaddr);
2261 err = hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ_CANCEL,
2262 sizeof(cp), &cp);
14a53664
JH
2263 if (err < 0)
2264 mgmt_pending_remove(cmd);
ff9ef578
JH
2265 else
2266 hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
14a53664 2267
30dc78e1 2268unlock:
09fd0de5 2269 hci_dev_unlock(hdev);
14a53664
JH
2270 hci_dev_put(hdev);
2271
2272 return err;
2273}
2274
650f726d 2275static int confirm_name(struct sock *sk, u16 index, void *data, u16 len)
561aafbc 2276{
650f726d 2277 struct mgmt_cp_confirm_name *cp = data;
561aafbc
JH
2278 struct inquiry_entry *e;
2279 struct hci_dev *hdev;
2280 int err;
2281
2282 BT_DBG("hci%u", index);
2283
2284 if (len != sizeof(*cp))
2285 return cmd_status(sk, index, MGMT_OP_CONFIRM_NAME,
2286 MGMT_STATUS_INVALID_PARAMS);
2287
2288 hdev = hci_dev_get(index);
2289 if (!hdev)
2290 return cmd_status(sk, index, MGMT_OP_CONFIRM_NAME,
2291 MGMT_STATUS_INVALID_PARAMS);
2292
2293 hci_dev_lock(hdev);
2294
30dc78e1
JH
2295 if (!hci_discovery_active(hdev)) {
2296 err = cmd_status(sk, index, MGMT_OP_CONFIRM_NAME,
2297 MGMT_STATUS_FAILED);
2298 goto failed;
2299 }
2300
561aafbc
JH
2301 e = hci_inquiry_cache_lookup_unknown(hdev, &cp->bdaddr);
2302 if (!e) {
2303 err = cmd_status (sk, index, MGMT_OP_CONFIRM_NAME,
2304 MGMT_STATUS_INVALID_PARAMS);
2305 goto failed;
2306 }
2307
2308 if (cp->name_known) {
2309 e->name_state = NAME_KNOWN;
2310 list_del(&e->list);
2311 } else {
2312 e->name_state = NAME_NEEDED;
a3d4e20a 2313 hci_inquiry_cache_update_resolve(hdev, e);
561aafbc
JH
2314 }
2315
2316 err = 0;
2317
2318failed:
2319 hci_dev_unlock(hdev);
2320
2321 return err;
2322}
2323
650f726d 2324static int block_device(struct sock *sk, u16 index, void *data, u16 len)
7fbec224
AJ
2325{
2326 struct hci_dev *hdev;
650f726d 2327 struct mgmt_cp_block_device *cp = data;
7fbec224
AJ
2328 int err;
2329
2330 BT_DBG("hci%u", index);
2331
7fbec224
AJ
2332 if (len != sizeof(*cp))
2333 return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
ca69b795 2334 MGMT_STATUS_INVALID_PARAMS);
7fbec224
AJ
2335
2336 hdev = hci_dev_get(index);
2337 if (!hdev)
2338 return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
ca69b795 2339 MGMT_STATUS_INVALID_PARAMS);
7fbec224 2340
09fd0de5 2341 hci_dev_lock(hdev);
5e762444 2342
88c1fe4b 2343 err = hci_blacklist_add(hdev, &cp->addr.bdaddr, cp->addr.type);
7fbec224 2344 if (err < 0)
ca69b795
JH
2345 err = cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
2346 MGMT_STATUS_FAILED);
7fbec224
AJ
2347 else
2348 err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE,
2349 NULL, 0);
5e762444 2350
09fd0de5 2351 hci_dev_unlock(hdev);
7fbec224
AJ
2352 hci_dev_put(hdev);
2353
2354 return err;
2355}
2356
650f726d 2357static int unblock_device(struct sock *sk, u16 index, void *data, u16 len)
7fbec224
AJ
2358{
2359 struct hci_dev *hdev;
650f726d 2360 struct mgmt_cp_unblock_device *cp = data;
7fbec224
AJ
2361 int err;
2362
2363 BT_DBG("hci%u", index);
2364
7fbec224
AJ
2365 if (len != sizeof(*cp))
2366 return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
ca69b795 2367 MGMT_STATUS_INVALID_PARAMS);
7fbec224
AJ
2368
2369 hdev = hci_dev_get(index);
2370 if (!hdev)
2371 return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
ca69b795 2372 MGMT_STATUS_INVALID_PARAMS);
7fbec224 2373
09fd0de5 2374 hci_dev_lock(hdev);
5e762444 2375
88c1fe4b 2376 err = hci_blacklist_del(hdev, &cp->addr.bdaddr, cp->addr.type);
7fbec224
AJ
2377
2378 if (err < 0)
ca69b795
JH
2379 err = cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
2380 MGMT_STATUS_INVALID_PARAMS);
7fbec224
AJ
2381 else
2382 err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE,
2383 NULL, 0);
5e762444 2384
09fd0de5 2385 hci_dev_unlock(hdev);
7fbec224
AJ
2386 hci_dev_put(hdev);
2387
2388 return err;
2389}
2390
f6422ec6 2391static int set_fast_connectable(struct sock *sk, u16 index,
650f726d 2392 void *data, u16 len)
f6422ec6
AJ
2393{
2394 struct hci_dev *hdev;
650f726d 2395 struct mgmt_mode *cp = data;
f6422ec6
AJ
2396 struct hci_cp_write_page_scan_activity acp;
2397 u8 type;
2398 int err;
2399
2400 BT_DBG("hci%u", index);
2401
2402 if (len != sizeof(*cp))
2403 return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2404 MGMT_STATUS_INVALID_PARAMS);
f6422ec6
AJ
2405
2406 hdev = hci_dev_get(index);
2407 if (!hdev)
2408 return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2409 MGMT_STATUS_INVALID_PARAMS);
f6422ec6
AJ
2410
2411 hci_dev_lock(hdev);
2412
f7c6869c 2413 if (cp->val) {
f6422ec6
AJ
2414 type = PAGE_SCAN_TYPE_INTERLACED;
2415 acp.interval = 0x0024; /* 22.5 msec page scan interval */
2416 } else {
2417 type = PAGE_SCAN_TYPE_STANDARD; /* default */
2418 acp.interval = 0x0800; /* default 1.28 sec page scan */
2419 }
2420
2421 acp.window = 0x0012; /* default 11.25 msec page scan window */
2422
2423 err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
2424 sizeof(acp), &acp);
2425 if (err < 0) {
2426 err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2427 MGMT_STATUS_FAILED);
f6422ec6
AJ
2428 goto done;
2429 }
2430
2431 err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type);
2432 if (err < 0) {
2433 err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2434 MGMT_STATUS_FAILED);
f6422ec6
AJ
2435 goto done;
2436 }
2437
2438 err = cmd_complete(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
2439 NULL, 0);
2440done:
2441 hci_dev_unlock(hdev);
2442 hci_dev_put(hdev);
2443
2444 return err;
2445}
2446
346af67b
VCG
2447static int load_long_term_keys(struct sock *sk, u16 index,
2448 void *cp_data, u16 len)
2449{
2450 struct hci_dev *hdev;
2451 struct mgmt_cp_load_long_term_keys *cp = cp_data;
2452 u16 key_count, expected_len;
2453 int i;
2454
2455 if (len < sizeof(*cp))
2456 return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS,
2457 EINVAL);
2458
2459 key_count = get_unaligned_le16(&cp->key_count);
2460
2461 expected_len = sizeof(*cp) + key_count *
2462 sizeof(struct mgmt_ltk_info);
2463 if (expected_len != len) {
2464 BT_ERR("load_keys: expected %u bytes, got %u bytes",
2465 len, expected_len);
2466 return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS,
2467 EINVAL);
2468 }
2469
2470 hdev = hci_dev_get(index);
2471 if (!hdev)
2472 return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS,
2473 ENODEV);
2474
2475 BT_DBG("hci%u key_count %u", index, key_count);
2476
2477 hci_dev_lock(hdev);
2478
2479 hci_smp_ltks_clear(hdev);
2480
2481 for (i = 0; i < key_count; i++) {
2482 struct mgmt_ltk_info *key = &cp->keys[i];
2483 u8 type;
2484
2485 if (key->master)
2486 type = HCI_SMP_LTK;
2487 else
2488 type = HCI_SMP_LTK_SLAVE;
2489
2490 hci_add_ltk(hdev, &key->addr.bdaddr, key->addr.type,
2491 type, 0, key->authenticated, key->val,
2492 key->enc_size, key->ediv, key->rand);
2493 }
2494
2495 hci_dev_unlock(hdev);
2496 hci_dev_put(hdev);
2497
2498 return 0;
2499}
2500
0381101f
JH
2501int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
2502{
650f726d
VCG
2503 void *buf;
2504 u8 *cp;
0381101f 2505 struct mgmt_hdr *hdr;
4e51eae9 2506 u16 opcode, index, len;
0381101f
JH
2507 int err;
2508
2509 BT_DBG("got %zu bytes", msglen);
2510
2511 if (msglen < sizeof(*hdr))
2512 return -EINVAL;
2513
e63a15ec 2514 buf = kmalloc(msglen, GFP_KERNEL);
0381101f
JH
2515 if (!buf)
2516 return -ENOMEM;
2517
2518 if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
2519 err = -EFAULT;
2520 goto done;
2521 }
2522
650f726d 2523 hdr = buf;
0381101f 2524 opcode = get_unaligned_le16(&hdr->opcode);
4e51eae9 2525 index = get_unaligned_le16(&hdr->index);
0381101f
JH
2526 len = get_unaligned_le16(&hdr->len);
2527
2528 if (len != msglen - sizeof(*hdr)) {
2529 err = -EINVAL;
2530 goto done;
2531 }
2532
650f726d
VCG
2533 cp = buf + sizeof(*hdr);
2534
0381101f 2535 switch (opcode) {
02d98129
JH
2536 case MGMT_OP_READ_VERSION:
2537 err = read_version(sk);
2538 break;
e70bb2e8
JH
2539 case MGMT_OP_READ_COMMANDS:
2540 err = read_commands(sk);
2541 break;
faba42eb
JH
2542 case MGMT_OP_READ_INDEX_LIST:
2543 err = read_index_list(sk);
2544 break;
f7b64e69 2545 case MGMT_OP_READ_INFO:
4e51eae9 2546 err = read_controller_info(sk, index);
f7b64e69 2547 break;
eec8d2bc 2548 case MGMT_OP_SET_POWERED:
650f726d 2549 err = set_powered(sk, index, cp, len);
eec8d2bc 2550 break;
73f22f62 2551 case MGMT_OP_SET_DISCOVERABLE:
650f726d 2552 err = set_discoverable(sk, index, cp, len);
73f22f62 2553 break;
9fbcbb45 2554 case MGMT_OP_SET_CONNECTABLE:
650f726d 2555 err = set_connectable(sk, index, cp, len);
9fbcbb45 2556 break;
f7c6869c 2557 case MGMT_OP_SET_FAST_CONNECTABLE:
650f726d 2558 err = set_fast_connectable(sk, index, cp, len);
f7c6869c 2559 break;
c542a06c 2560 case MGMT_OP_SET_PAIRABLE:
650f726d 2561 err = set_pairable(sk, index, cp, len);
c542a06c 2562 break;
33ef95ed
JH
2563 case MGMT_OP_SET_LINK_SECURITY:
2564 err = set_link_security(sk, index, cp, len);
2565 break;
ed2c4ee3
JH
2566 case MGMT_OP_SET_SSP:
2567 err = set_ssp(sk, index, cp, len);
2568 break;
2aeb9a1a 2569 case MGMT_OP_ADD_UUID:
650f726d 2570 err = add_uuid(sk, index, cp, len);
2aeb9a1a
JH
2571 break;
2572 case MGMT_OP_REMOVE_UUID:
650f726d 2573 err = remove_uuid(sk, index, cp, len);
2aeb9a1a 2574 break;
1aff6f09 2575 case MGMT_OP_SET_DEV_CLASS:
650f726d 2576 err = set_dev_class(sk, index, cp, len);
1aff6f09 2577 break;
86742e1e 2578 case MGMT_OP_LOAD_LINK_KEYS:
650f726d 2579 err = load_link_keys(sk, index, cp, len);
55ed8ca1 2580 break;
8962ee74 2581 case MGMT_OP_DISCONNECT:
650f726d 2582 err = disconnect(sk, index, cp, len);
8962ee74 2583 break;
2784eb41 2584 case MGMT_OP_GET_CONNECTIONS:
8ce6284e 2585 err = get_connections(sk, index);
2784eb41 2586 break;
980e1a53 2587 case MGMT_OP_PIN_CODE_REPLY:
650f726d 2588 err = pin_code_reply(sk, index, cp, len);
980e1a53
JH
2589 break;
2590 case MGMT_OP_PIN_CODE_NEG_REPLY:
650f726d 2591 err = pin_code_neg_reply(sk, index, cp, len);
980e1a53 2592 break;
17fa4b9d 2593 case MGMT_OP_SET_IO_CAPABILITY:
650f726d 2594 err = set_io_capability(sk, index, cp, len);
17fa4b9d 2595 break;
e9a416b5 2596 case MGMT_OP_PAIR_DEVICE:
650f726d 2597 err = pair_device(sk, index, cp, len);
e9a416b5 2598 break;
28424707
JH
2599 case MGMT_OP_CANCEL_PAIR_DEVICE:
2600 err = cancel_pair_device(sk, index, buf + sizeof(*hdr), len);
2601 break;
124f6e35
JH
2602 case MGMT_OP_UNPAIR_DEVICE:
2603 err = unpair_device(sk, index, cp, len);
2604 break;
a5c29683 2605 case MGMT_OP_USER_CONFIRM_REPLY:
650f726d 2606 err = user_confirm_reply(sk, index, cp, len);
a5c29683
JH
2607 break;
2608 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
650f726d 2609 err = user_confirm_neg_reply(sk, index, cp, len);
a5c29683 2610 break;
604086b7 2611 case MGMT_OP_USER_PASSKEY_REPLY:
650f726d 2612 err = user_passkey_reply(sk, index, cp, len);
604086b7
BG
2613 break;
2614 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
650f726d 2615 err = user_passkey_neg_reply(sk, index, cp, len);
a5c29683 2616 break;
b312b161 2617 case MGMT_OP_SET_LOCAL_NAME:
650f726d 2618 err = set_local_name(sk, index, cp, len);
b312b161 2619 break;
c35938b2
SJ
2620 case MGMT_OP_READ_LOCAL_OOB_DATA:
2621 err = read_local_oob_data(sk, index);
2622 break;
2763eda6 2623 case MGMT_OP_ADD_REMOTE_OOB_DATA:
650f726d 2624 err = add_remote_oob_data(sk, index, cp, len);
2763eda6
SJ
2625 break;
2626 case MGMT_OP_REMOVE_REMOTE_OOB_DATA:
650f726d 2627 err = remove_remote_oob_data(sk, index, cp, len);
2763eda6 2628 break;
14a53664 2629 case MGMT_OP_START_DISCOVERY:
650f726d 2630 err = start_discovery(sk, index, cp, len);
14a53664
JH
2631 break;
2632 case MGMT_OP_STOP_DISCOVERY:
2633 err = stop_discovery(sk, index);
2634 break;
561aafbc 2635 case MGMT_OP_CONFIRM_NAME:
650f726d 2636 err = confirm_name(sk, index, cp, len);
561aafbc 2637 break;
7fbec224 2638 case MGMT_OP_BLOCK_DEVICE:
650f726d 2639 err = block_device(sk, index, cp, len);
7fbec224
AJ
2640 break;
2641 case MGMT_OP_UNBLOCK_DEVICE:
650f726d 2642 err = unblock_device(sk, index, cp, len);
7fbec224 2643 break;
346af67b
VCG
2644 case MGMT_OP_LOAD_LONG_TERM_KEYS:
2645 err = load_long_term_keys(sk, index, cp, len);
2646 break;
0381101f
JH
2647 default:
2648 BT_DBG("Unknown op %u", opcode);
ca69b795
JH
2649 err = cmd_status(sk, index, opcode,
2650 MGMT_STATUS_UNKNOWN_COMMAND);
0381101f
JH
2651 break;
2652 }
2653
e41d8b4e
JH
2654 if (err < 0)
2655 goto done;
2656
0381101f
JH
2657 err = msglen;
2658
2659done:
2660 kfree(buf);
2661 return err;
2662}
c71e97bf 2663
b24752fe
JH
2664static void cmd_status_rsp(struct pending_cmd *cmd, void *data)
2665{
2666 u8 *status = data;
2667
2668 cmd_status(cmd->sk, cmd->index, cmd->opcode, *status);
2669 mgmt_pending_remove(cmd);
2670}
2671
744cf19e 2672int mgmt_index_added(struct hci_dev *hdev)
c71e97bf 2673{
744cf19e 2674 return mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL);
c71e97bf
JH
2675}
2676
744cf19e 2677int mgmt_index_removed(struct hci_dev *hdev)
c71e97bf 2678{
b24752fe
JH
2679 u8 status = ENODEV;
2680
744cf19e 2681 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
b24752fe 2682
744cf19e 2683 return mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL);
eec8d2bc
JH
2684}
2685
73f22f62 2686struct cmd_lookup {
eec8d2bc 2687 struct sock *sk;
69ab39ea 2688 struct hci_dev *hdev;
eec8d2bc
JH
2689};
2690
69ab39ea 2691static void settings_rsp(struct pending_cmd *cmd, void *data)
eec8d2bc 2692{
73f22f62 2693 struct cmd_lookup *match = data;
eec8d2bc 2694
69ab39ea 2695 send_settings_rsp(cmd->sk, cmd->opcode, match->hdev);
eec8d2bc
JH
2696
2697 list_del(&cmd->list);
2698
2699 if (match->sk == NULL) {
2700 match->sk = cmd->sk;
2701 sock_hold(match->sk);
2702 }
2703
2704 mgmt_pending_free(cmd);
c71e97bf 2705}
5add6af8 2706
744cf19e 2707int mgmt_powered(struct hci_dev *hdev, u8 powered)
5add6af8 2708{
76a7f3a4 2709 struct cmd_lookup match = { NULL, hdev };
69ab39ea 2710 __le32 ev;
7bb895d6 2711 int err;
5add6af8 2712
69ab39ea 2713 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
5add6af8 2714
b24752fe
JH
2715 if (!powered) {
2716 u8 status = ENETDOWN;
744cf19e 2717 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
b24752fe
JH
2718 }
2719
69ab39ea 2720 ev = cpu_to_le32(get_current_settings(hdev));
eec8d2bc 2721
7bb895d6 2722 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev),
69ab39ea 2723 match.sk);
eec8d2bc
JH
2724
2725 if (match.sk)
2726 sock_put(match.sk);
2727
7bb895d6 2728 return err;
5add6af8 2729}
73f22f62 2730
744cf19e 2731int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
73f22f62 2732{
76a7f3a4 2733 struct cmd_lookup match = { NULL, hdev };
69ab39ea 2734 __le32 ev;
7bb895d6 2735 int err;
73f22f62 2736
69ab39ea 2737 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, settings_rsp, &match);
72a734ec 2738
69ab39ea 2739 ev = cpu_to_le32(get_current_settings(hdev));
73f22f62 2740
7bb895d6 2741 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev),
4e51eae9 2742 match.sk);
73f22f62
JH
2743 if (match.sk)
2744 sock_put(match.sk);
2745
7bb895d6 2746 return err;
73f22f62 2747}
9fbcbb45 2748
744cf19e 2749int mgmt_connectable(struct hci_dev *hdev, u8 connectable)
9fbcbb45 2750{
69ab39ea 2751 __le32 ev;
76a7f3a4 2752 struct cmd_lookup match = { NULL, hdev };
7bb895d6 2753 int err;
9fbcbb45 2754
69ab39ea
JH
2755 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, settings_rsp,
2756 &match);
9fbcbb45 2757
69ab39ea 2758 ev = cpu_to_le32(get_current_settings(hdev));
9fbcbb45 2759
7bb895d6 2760 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), match.sk);
9fbcbb45
JH
2761
2762 if (match.sk)
2763 sock_put(match.sk);
2764
7bb895d6 2765 return err;
9fbcbb45 2766}
55ed8ca1 2767
744cf19e 2768int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status)
2d7cee58 2769{
ca69b795
JH
2770 u8 mgmt_err = mgmt_status(status);
2771
2d7cee58 2772 if (scan & SCAN_PAGE)
744cf19e 2773 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev,
ca69b795 2774 cmd_status_rsp, &mgmt_err);
2d7cee58
JH
2775
2776 if (scan & SCAN_INQUIRY)
744cf19e 2777 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev,
ca69b795 2778 cmd_status_rsp, &mgmt_err);
2d7cee58
JH
2779
2780 return 0;
2781}
2782
744cf19e
JH
2783int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
2784 u8 persistent)
55ed8ca1 2785{
86742e1e 2786 struct mgmt_ev_new_link_key ev;
55ed8ca1 2787
a492cd52 2788 memset(&ev, 0, sizeof(ev));
55ed8ca1 2789
a492cd52 2790 ev.store_hint = persistent;
d753fdc4
JH
2791 bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
2792 ev.key.addr.type = MGMT_ADDR_BREDR;
a492cd52
VCG
2793 ev.key.type = key->type;
2794 memcpy(ev.key.val, key->val, 16);
2795 ev.key.pin_len = key->pin_len;
55ed8ca1 2796
744cf19e 2797 return mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL);
55ed8ca1 2798}
f7520543 2799
346af67b
VCG
2800int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent)
2801{
2802 struct mgmt_ev_new_long_term_key ev;
2803
2804 memset(&ev, 0, sizeof(ev));
2805
2806 ev.store_hint = persistent;
2807 bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
2808 ev.key.addr.type = key->bdaddr_type;
2809 ev.key.authenticated = key->authenticated;
2810 ev.key.enc_size = key->enc_size;
2811 ev.key.ediv = key->ediv;
2812
2813 if (key->type == HCI_SMP_LTK)
2814 ev.key.master = 1;
2815
2816 memcpy(ev.key.rand, key->rand, sizeof(key->rand));
2817 memcpy(ev.key.val, key->val, sizeof(key->val));
2818
2819 return mgmt_event(MGMT_EV_NEW_LONG_TERM_KEY, hdev,
2820 &ev, sizeof(ev), NULL);
2821}
2822
afc747a6 2823int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
b644ba33
JH
2824 u8 addr_type, u8 *name, u8 name_len,
2825 u8 *dev_class)
f7520543 2826{
b644ba33
JH
2827 char buf[512];
2828 struct mgmt_ev_device_connected *ev = (void *) buf;
2829 u16 eir_len = 0;
f7520543 2830
b644ba33
JH
2831 bacpy(&ev->addr.bdaddr, bdaddr);
2832 ev->addr.type = link_to_mgmt(link_type, addr_type);
f7520543 2833
b644ba33
JH
2834 if (name_len > 0)
2835 eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE,
2836 name, name_len);
2837
2838 if (dev_class && memcmp(dev_class, "\0\0\0", 3) != 0)
2839 eir_len = eir_append_data(&ev->eir[eir_len], eir_len,
2840 EIR_CLASS_OF_DEV, dev_class, 3);
2841
2842 put_unaligned_le16(eir_len, &ev->eir_len);
2843
2844 return mgmt_event(MGMT_EV_DEVICE_CONNECTED, hdev, buf,
2845 sizeof(*ev) + eir_len, NULL);
f7520543
JH
2846}
2847
8962ee74
JH
2848static void disconnect_rsp(struct pending_cmd *cmd, void *data)
2849{
c68fb7ff 2850 struct mgmt_cp_disconnect *cp = cmd->param;
8962ee74 2851 struct sock **sk = data;
a38528f1 2852 struct mgmt_rp_disconnect rp;
8962ee74 2853
88c3df13
JH
2854 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
2855 rp.addr.type = cp->addr.type;
37d9ef76 2856 rp.status = 0;
8962ee74 2857
4e51eae9 2858 cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, &rp, sizeof(rp));
8962ee74
JH
2859
2860 *sk = cmd->sk;
2861 sock_hold(*sk);
2862
a664b5bc 2863 mgmt_pending_remove(cmd);
8962ee74
JH
2864}
2865
124f6e35 2866static void unpair_device_rsp(struct pending_cmd *cmd, void *data)
a8a1d19e 2867{
b1078ad0 2868 struct hci_dev *hdev = data;
124f6e35
JH
2869 struct mgmt_cp_unpair_device *cp = cmd->param;
2870 struct mgmt_rp_unpair_device rp;
a8a1d19e
JH
2871
2872 memset(&rp, 0, sizeof(rp));
124f6e35
JH
2873 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
2874 rp.addr.type = cp->addr.type;
a8a1d19e 2875
b1078ad0
JH
2876 device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, cmd->sk);
2877
2878 cmd_complete(cmd->sk, cmd->index, cmd->opcode, &rp, sizeof(rp));
a8a1d19e
JH
2879
2880 mgmt_pending_remove(cmd);
2881}
2882
afc747a6
JH
2883int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
2884 u8 link_type, u8 addr_type)
f7520543 2885{
4c659c39 2886 struct mgmt_addr_info ev;
8962ee74
JH
2887 struct sock *sk = NULL;
2888 int err;
2889
744cf19e 2890 mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk);
f7520543 2891
f7520543 2892 bacpy(&ev.bdaddr, bdaddr);
48264f06 2893 ev.type = link_to_mgmt(link_type, addr_type);
f7520543 2894
afc747a6
JH
2895 err = mgmt_event(MGMT_EV_DEVICE_DISCONNECTED, hdev, &ev, sizeof(ev),
2896 sk);
8962ee74
JH
2897
2898 if (sk)
2899 sock_put(sk);
2900
124f6e35 2901 mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp,
b1078ad0 2902 hdev);
a8a1d19e 2903
8962ee74
JH
2904 return err;
2905}
2906
88c3df13
JH
2907int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
2908 u8 link_type, u8 addr_type, u8 status)
8962ee74 2909{
88c3df13 2910 struct mgmt_rp_disconnect rp;
8962ee74
JH
2911 struct pending_cmd *cmd;
2912 int err;
2913
2e58ef3e 2914 cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev);
8962ee74
JH
2915 if (!cmd)
2916 return -ENOENT;
2917
88c3df13
JH
2918 bacpy(&rp.addr.bdaddr, bdaddr);
2919 rp.addr.type = link_to_mgmt(link_type, addr_type);
2920 rp.status = mgmt_status(status);
37d9ef76 2921
88c3df13 2922 err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT,
37d9ef76 2923 &rp, sizeof(rp));
8962ee74 2924
a664b5bc 2925 mgmt_pending_remove(cmd);
8962ee74 2926
b1078ad0
JH
2927 mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp,
2928 hdev);
8962ee74 2929 return err;
f7520543 2930}
17d5c04c 2931
48264f06
JH
2932int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
2933 u8 addr_type, u8 status)
17d5c04c
JH
2934{
2935 struct mgmt_ev_connect_failed ev;
2936
4c659c39 2937 bacpy(&ev.addr.bdaddr, bdaddr);
48264f06 2938 ev.addr.type = link_to_mgmt(link_type, addr_type);
ca69b795 2939 ev.status = mgmt_status(status);
17d5c04c 2940
744cf19e 2941 return mgmt_event(MGMT_EV_CONNECT_FAILED, hdev, &ev, sizeof(ev), NULL);
17d5c04c 2942}
980e1a53 2943
744cf19e 2944int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure)
980e1a53
JH
2945{
2946 struct mgmt_ev_pin_code_request ev;
2947
980e1a53 2948 bacpy(&ev.bdaddr, bdaddr);
a770bb5a 2949 ev.secure = secure;
980e1a53 2950
744cf19e 2951 return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, hdev, &ev, sizeof(ev),
4e51eae9 2952 NULL);
980e1a53
JH
2953}
2954
744cf19e
JH
2955int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
2956 u8 status)
980e1a53
JH
2957{
2958 struct pending_cmd *cmd;
ac56fb13 2959 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
2960 int err;
2961
2e58ef3e 2962 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev);
980e1a53
JH
2963 if (!cmd)
2964 return -ENOENT;
2965
ac56fb13 2966 bacpy(&rp.bdaddr, bdaddr);
ca69b795 2967 rp.status = mgmt_status(status);
ac56fb13 2968
744cf19e 2969 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, &rp,
4e51eae9 2970 sizeof(rp));
980e1a53 2971
a664b5bc 2972 mgmt_pending_remove(cmd);
980e1a53
JH
2973
2974 return err;
2975}
2976
744cf19e
JH
2977int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
2978 u8 status)
980e1a53
JH
2979{
2980 struct pending_cmd *cmd;
ac56fb13 2981 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
2982 int err;
2983
2e58ef3e 2984 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev);
980e1a53
JH
2985 if (!cmd)
2986 return -ENOENT;
2987
ac56fb13 2988 bacpy(&rp.bdaddr, bdaddr);
ca69b795 2989 rp.status = mgmt_status(status);
ac56fb13 2990
744cf19e 2991 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY, &rp,
4e51eae9 2992 sizeof(rp));
980e1a53 2993
a664b5bc 2994 mgmt_pending_remove(cmd);
980e1a53
JH
2995
2996 return err;
2997}
a5c29683 2998
744cf19e 2999int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
272d90df
JH
3000 u8 link_type, u8 addr_type, __le32 value,
3001 u8 confirm_hint)
a5c29683
JH
3002{
3003 struct mgmt_ev_user_confirm_request ev;
3004
744cf19e 3005 BT_DBG("%s", hdev->name);
a5c29683 3006
272d90df
JH
3007 bacpy(&ev.addr.bdaddr, bdaddr);
3008 ev.addr.type = link_to_mgmt(link_type, addr_type);
55bc1a37 3009 ev.confirm_hint = confirm_hint;
a5c29683
JH
3010 put_unaligned_le32(value, &ev.value);
3011
744cf19e 3012 return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, hdev, &ev, sizeof(ev),
4e51eae9 3013 NULL);
a5c29683
JH
3014}
3015
272d90df
JH
3016int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
3017 u8 link_type, u8 addr_type)
604086b7
BG
3018{
3019 struct mgmt_ev_user_passkey_request ev;
3020
3021 BT_DBG("%s", hdev->name);
3022
272d90df
JH
3023 bacpy(&ev.addr.bdaddr, bdaddr);
3024 ev.addr.type = link_to_mgmt(link_type, addr_type);
604086b7
BG
3025
3026 return mgmt_event(MGMT_EV_USER_PASSKEY_REQUEST, hdev, &ev, sizeof(ev),
3027 NULL);
3028}
3029
0df4c185 3030static int user_pairing_resp_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
272d90df
JH
3031 u8 link_type, u8 addr_type, u8 status,
3032 u8 opcode)
a5c29683
JH
3033{
3034 struct pending_cmd *cmd;
3035 struct mgmt_rp_user_confirm_reply rp;
3036 int err;
3037
2e58ef3e 3038 cmd = mgmt_pending_find(opcode, hdev);
a5c29683
JH
3039 if (!cmd)
3040 return -ENOENT;
3041
272d90df
JH
3042 bacpy(&rp.addr.bdaddr, bdaddr);
3043 rp.addr.type = link_to_mgmt(link_type, addr_type);
ca69b795 3044 rp.status = mgmt_status(status);
744cf19e 3045 err = cmd_complete(cmd->sk, hdev->id, opcode, &rp, sizeof(rp));
a5c29683 3046
a664b5bc 3047 mgmt_pending_remove(cmd);
a5c29683
JH
3048
3049 return err;
3050}
3051
744cf19e 3052int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
272d90df 3053 u8 link_type, u8 addr_type, u8 status)
a5c29683 3054{
272d90df
JH
3055 return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type,
3056 status, MGMT_OP_USER_CONFIRM_REPLY);
a5c29683
JH
3057}
3058
272d90df
JH
3059int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
3060 u8 link_type, u8 addr_type, u8 status)
a5c29683 3061{
272d90df
JH
3062 return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type,
3063 status, MGMT_OP_USER_CONFIRM_NEG_REPLY);
a5c29683 3064}
2a611692 3065
604086b7 3066int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
272d90df 3067 u8 link_type, u8 addr_type, u8 status)
604086b7 3068{
272d90df
JH
3069 return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type,
3070 status, MGMT_OP_USER_PASSKEY_REPLY);
604086b7
BG
3071}
3072
272d90df
JH
3073int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
3074 u8 link_type, u8 addr_type, u8 status)
604086b7 3075{
272d90df
JH
3076 return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type,
3077 status, MGMT_OP_USER_PASSKEY_NEG_REPLY);
604086b7
BG
3078}
3079
bab73cb6
JH
3080int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
3081 u8 addr_type, u8 status)
2a611692
JH
3082{
3083 struct mgmt_ev_auth_failed ev;
3084
bab73cb6
JH
3085 bacpy(&ev.addr.bdaddr, bdaddr);
3086 ev.addr.type = link_to_mgmt(link_type, addr_type);
ca69b795 3087 ev.status = mgmt_status(status);
2a611692 3088
744cf19e 3089 return mgmt_event(MGMT_EV_AUTH_FAILED, hdev, &ev, sizeof(ev), NULL);
2a611692 3090}
b312b161 3091
33ef95ed
JH
3092int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
3093{
3094 struct cmd_lookup match = { NULL, hdev };
3095 __le32 ev;
3096 int err;
3097
3098 if (status) {
3099 u8 mgmt_err = mgmt_status(status);
3100 mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev,
3101 cmd_status_rsp, &mgmt_err);
3102 return 0;
3103 }
3104
3105 mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp,
3106 &match);
3107
3108 ev = cpu_to_le32(get_current_settings(hdev));
3109 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), match.sk);
3110
3111 if (match.sk)
3112 sock_put(match.sk);
3113
3114 return err;
3115}
3116
ed2c4ee3
JH
3117int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 status)
3118{
3119 struct cmd_lookup match = { NULL, hdev };
3120 __le32 ev;
3121 int err;
3122
3123 if (status) {
3124 u8 mgmt_err = mgmt_status(status);
3125 mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev,
3126 cmd_status_rsp, &mgmt_err);
3127 return 0;
3128 }
3129
3130 mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match);
3131
3132 ev = cpu_to_le32(get_current_settings(hdev));
3133 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), match.sk);
3134
3135 if (match.sk)
3136 sock_put(match.sk);
3137
3138 return err;
3139}
3140
744cf19e 3141int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status)
b312b161
JH
3142{
3143 struct pending_cmd *cmd;
3144 struct mgmt_cp_set_local_name ev;
3145 int err;
3146
3147 memset(&ev, 0, sizeof(ev));
3148 memcpy(ev.name, name, HCI_MAX_NAME_LENGTH);
3149
2e58ef3e 3150 cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev);
b312b161
JH
3151 if (!cmd)
3152 goto send_event;
3153
3154 if (status) {
744cf19e 3155 err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
ca69b795 3156 mgmt_status(status));
b312b161
JH
3157 goto failed;
3158 }
3159
744cf19e 3160 update_eir(hdev);
80a1e1db 3161
744cf19e 3162 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, &ev,
b312b161
JH
3163 sizeof(ev));
3164 if (err < 0)
3165 goto failed;
3166
3167send_event:
744cf19e 3168 err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev),
b312b161
JH
3169 cmd ? cmd->sk : NULL);
3170
3171failed:
3172 if (cmd)
3173 mgmt_pending_remove(cmd);
3174 return err;
3175}
c35938b2 3176
744cf19e
JH
3177int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
3178 u8 *randomizer, u8 status)
c35938b2
SJ
3179{
3180 struct pending_cmd *cmd;
3181 int err;
3182
744cf19e 3183 BT_DBG("%s status %u", hdev->name, status);
c35938b2 3184
2e58ef3e 3185 cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev);
c35938b2
SJ
3186 if (!cmd)
3187 return -ENOENT;
3188
3189 if (status) {
744cf19e 3190 err = cmd_status(cmd->sk, hdev->id,
ca69b795
JH
3191 MGMT_OP_READ_LOCAL_OOB_DATA,
3192 mgmt_status(status));
c35938b2
SJ
3193 } else {
3194 struct mgmt_rp_read_local_oob_data rp;
3195
3196 memcpy(rp.hash, hash, sizeof(rp.hash));
3197 memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer));
3198
744cf19e
JH
3199 err = cmd_complete(cmd->sk, hdev->id,
3200 MGMT_OP_READ_LOCAL_OOB_DATA,
3201 &rp, sizeof(rp));
c35938b2
SJ
3202 }
3203
3204 mgmt_pending_remove(cmd);
3205
3206 return err;
3207}
e17acd40 3208
48264f06 3209int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
561aafbc 3210 u8 addr_type, u8 *dev_class, s8 rssi,
e319d2e7 3211 u8 cfm_name, u8 *eir, u16 eir_len)
e17acd40 3212{
e319d2e7
JH
3213 char buf[512];
3214 struct mgmt_ev_device_found *ev = (void *) buf;
1dc06093 3215 size_t ev_size;
e17acd40 3216
1dc06093
JH
3217 /* Leave 5 bytes for a potential CoD field */
3218 if (sizeof(*ev) + eir_len + 5 > sizeof(buf))
7d262f86
AG
3219 return -EINVAL;
3220
1dc06093
JH
3221 memset(buf, 0, sizeof(buf));
3222
e319d2e7
JH
3223 bacpy(&ev->addr.bdaddr, bdaddr);
3224 ev->addr.type = link_to_mgmt(link_type, addr_type);
3225 ev->rssi = rssi;
3226 ev->confirm_name = cfm_name;
e17acd40 3227
1dc06093 3228 if (eir_len > 0)
e319d2e7 3229 memcpy(ev->eir, eir, eir_len);
e17acd40 3230
1dc06093
JH
3231 if (dev_class && !eir_has_data_type(ev->eir, eir_len, EIR_CLASS_OF_DEV))
3232 eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV,
3233 dev_class, 3);
3234
3235 put_unaligned_le16(eir_len, &ev->eir_len);
3236
3237 ev_size = sizeof(*ev) + eir_len;
f8523598 3238
e319d2e7 3239 return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL);
e17acd40 3240}
a88a9652 3241
b644ba33
JH
3242int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
3243 u8 addr_type, s8 rssi, u8 *name, u8 name_len)
a88a9652 3244{
b644ba33
JH
3245 struct mgmt_ev_device_found *ev;
3246 char buf[sizeof(*ev) + HCI_MAX_NAME_LENGTH + 2];
3247 u16 eir_len;
a88a9652 3248
b644ba33 3249 ev = (struct mgmt_ev_device_found *) buf;
a88a9652 3250
b644ba33
JH
3251 memset(buf, 0, sizeof(buf));
3252
3253 bacpy(&ev->addr.bdaddr, bdaddr);
3254 ev->addr.type = link_to_mgmt(link_type, addr_type);
3255 ev->rssi = rssi;
3256
3257 eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, name,
3258 name_len);
3259
3260 put_unaligned_le16(eir_len, &ev->eir_len);
a88a9652 3261
053c7e0c
JH
3262 return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev,
3263 sizeof(*ev) + eir_len, NULL);
a88a9652 3264}
314b2381 3265
7a135109 3266int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status)
164a6e78
JH
3267{
3268 struct pending_cmd *cmd;
3269 int err;
3270
203159d4
AG
3271 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
3272
2e58ef3e 3273 cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev);
164a6e78
JH
3274 if (!cmd)
3275 return -ENOENT;
3276
ca69b795 3277 err = cmd_status(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status));
164a6e78
JH
3278 mgmt_pending_remove(cmd);
3279
3280 return err;
3281}
3282
e6d465cb
AG
3283int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status)
3284{
3285 struct pending_cmd *cmd;
3286 int err;
3287
3288 cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev);
3289 if (!cmd)
3290 return -ENOENT;
3291
e75a8b0c 3292 err = cmd_status(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status));
164a6e78
JH
3293 mgmt_pending_remove(cmd);
3294
3295 return err;
3296}
3297
744cf19e 3298int mgmt_discovering(struct hci_dev *hdev, u8 discovering)
314b2381 3299{
164a6e78
JH
3300 struct pending_cmd *cmd;
3301
343fb145
AG
3302 BT_DBG("%s discovering %u", hdev->name, discovering);
3303
164a6e78 3304 if (discovering)
2e58ef3e 3305 cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev);
164a6e78 3306 else
2e58ef3e 3307 cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev);
164a6e78
JH
3308
3309 if (cmd != NULL) {
744cf19e 3310 cmd_complete(cmd->sk, hdev->id, cmd->opcode, NULL, 0);
164a6e78
JH
3311 mgmt_pending_remove(cmd);
3312 }
3313
744cf19e 3314 return mgmt_event(MGMT_EV_DISCOVERING, hdev, &discovering,
314b2381
JH
3315 sizeof(discovering), NULL);
3316}
5e762444 3317
88c1fe4b 3318int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
5e762444
AJ
3319{
3320 struct pending_cmd *cmd;
3321 struct mgmt_ev_device_blocked ev;
3322
2e58ef3e 3323 cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, hdev);
5e762444 3324
88c1fe4b
JH
3325 bacpy(&ev.addr.bdaddr, bdaddr);
3326 ev.addr.type = type;
5e762444 3327
744cf19e
JH
3328 return mgmt_event(MGMT_EV_DEVICE_BLOCKED, hdev, &ev, sizeof(ev),
3329 cmd ? cmd->sk : NULL);
5e762444
AJ
3330}
3331
88c1fe4b 3332int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
5e762444
AJ
3333{
3334 struct pending_cmd *cmd;
3335 struct mgmt_ev_device_unblocked ev;
3336
2e58ef3e 3337 cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, hdev);
5e762444 3338
88c1fe4b
JH
3339 bacpy(&ev.addr.bdaddr, bdaddr);
3340 ev.addr.type = type;
5e762444 3341
744cf19e
JH
3342 return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &ev, sizeof(ev),
3343 cmd ? cmd->sk : NULL);
5e762444 3344}
This page took 0.276049 seconds and 5 git commands to generate.