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