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