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