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