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