Bluetooth: Add MGMT handlers for dealing with SMP LTK's
[deliverable/linux.git] / net / bluetooth / mgmt.c
CommitLineData
0381101f
JH
1/*
2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2010 Nokia Corporation
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation;
8
9 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20 SOFTWARE IS DISCLAIMED.
21*/
22
23/* Bluetooth HCI Management interface */
24
ca69b795 25#include <linux/kernel.h>
72359753 26#include <linux/uaccess.h>
3a9a231d 27#include <linux/module.h>
0381101f
JH
28#include <asm/unaligned.h>
29
30#include <net/bluetooth/bluetooth.h>
31#include <net/bluetooth/hci_core.h>
32#include <net/bluetooth/mgmt.h>
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
55ed8ca1
JH
1092 err = hci_remove_link_key(hdev, &cp->bdaddr);
1093 if (err < 0) {
ca69b795 1094 rp.status = MGMT_STATUS_NOT_PAIRED;
55ed8ca1
JH
1095 goto unlock;
1096 }
1097
a8a1d19e
JH
1098 if (!test_bit(HCI_UP, &hdev->flags) || !cp->disconnect) {
1099 err = cmd_complete(sk, index, MGMT_OP_REMOVE_KEYS, &rp,
1100 sizeof(rp));
55ed8ca1 1101 goto unlock;
a8a1d19e 1102 }
55ed8ca1
JH
1103
1104 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
a8a1d19e
JH
1105 if (!conn) {
1106 err = cmd_complete(sk, index, MGMT_OP_REMOVE_KEYS, &rp,
1107 sizeof(rp));
1108 goto unlock;
1109 }
55ed8ca1 1110
a8a1d19e
JH
1111 cmd = mgmt_pending_add(sk, MGMT_OP_REMOVE_KEYS, hdev, cp, sizeof(*cp));
1112 if (!cmd) {
1113 err = -ENOMEM;
1114 goto unlock;
55ed8ca1
JH
1115 }
1116
a8a1d19e
JH
1117 put_unaligned_le16(conn->handle, &dc.handle);
1118 dc.reason = 0x13; /* Remote User Terminated Connection */
1119 err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc);
1120 if (err < 0)
1121 mgmt_pending_remove(cmd);
1122
55ed8ca1 1123unlock:
ca69b795 1124 if (err < 0)
a8a1d19e
JH
1125 err = cmd_complete(sk, index, MGMT_OP_REMOVE_KEYS, &rp,
1126 sizeof(rp));
09fd0de5 1127 hci_dev_unlock(hdev);
55ed8ca1
JH
1128 hci_dev_put(hdev);
1129
1130 return err;
1131}
1132
650f726d 1133static int disconnect(struct sock *sk, u16 index, void *data, u16 len)
8962ee74
JH
1134{
1135 struct hci_dev *hdev;
650f726d 1136 struct mgmt_cp_disconnect *cp = data;
8962ee74 1137 struct hci_cp_disconnect dc;
366a0336 1138 struct pending_cmd *cmd;
8962ee74 1139 struct hci_conn *conn;
8962ee74
JH
1140 int err;
1141
1142 BT_DBG("");
1143
bdce7baf 1144 if (len != sizeof(*cp))
ca69b795
JH
1145 return cmd_status(sk, index, MGMT_OP_DISCONNECT,
1146 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1147
4e51eae9 1148 hdev = hci_dev_get(index);
8962ee74 1149 if (!hdev)
ca69b795
JH
1150 return cmd_status(sk, index, MGMT_OP_DISCONNECT,
1151 MGMT_STATUS_INVALID_PARAMS);
8962ee74 1152
09fd0de5 1153 hci_dev_lock(hdev);
8962ee74
JH
1154
1155 if (!test_bit(HCI_UP, &hdev->flags)) {
ca69b795
JH
1156 err = cmd_status(sk, index, MGMT_OP_DISCONNECT,
1157 MGMT_STATUS_NOT_POWERED);
8962ee74
JH
1158 goto failed;
1159 }
1160
2e58ef3e 1161 if (mgmt_pending_find(MGMT_OP_DISCONNECT, hdev)) {
ca69b795
JH
1162 err = cmd_status(sk, index, MGMT_OP_DISCONNECT,
1163 MGMT_STATUS_BUSY);
8962ee74
JH
1164 goto failed;
1165 }
1166
1167 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
365227e5
VCG
1168 if (!conn)
1169 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->bdaddr);
1170
8962ee74 1171 if (!conn) {
ca69b795
JH
1172 err = cmd_status(sk, index, MGMT_OP_DISCONNECT,
1173 MGMT_STATUS_NOT_CONNECTED);
8962ee74
JH
1174 goto failed;
1175 }
1176
2e58ef3e 1177 cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, hdev, data, len);
366a0336
JH
1178 if (!cmd) {
1179 err = -ENOMEM;
8962ee74 1180 goto failed;
366a0336 1181 }
8962ee74
JH
1182
1183 put_unaligned_le16(conn->handle, &dc.handle);
1184 dc.reason = 0x13; /* Remote User Terminated Connection */
1185
1186 err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc);
1187 if (err < 0)
a664b5bc 1188 mgmt_pending_remove(cmd);
8962ee74
JH
1189
1190failed:
09fd0de5 1191 hci_dev_unlock(hdev);
8962ee74
JH
1192 hci_dev_put(hdev);
1193
1194 return err;
1195}
1196
48264f06 1197static u8 link_to_mgmt(u8 link_type, u8 addr_type)
4c659c39
JH
1198{
1199 switch (link_type) {
1200 case LE_LINK:
48264f06
JH
1201 switch (addr_type) {
1202 case ADDR_LE_DEV_PUBLIC:
1203 return MGMT_ADDR_LE_PUBLIC;
1204 case ADDR_LE_DEV_RANDOM:
1205 return MGMT_ADDR_LE_RANDOM;
1206 default:
1207 return MGMT_ADDR_INVALID;
1208 }
4c659c39
JH
1209 case ACL_LINK:
1210 return MGMT_ADDR_BREDR;
1211 default:
1212 return MGMT_ADDR_INVALID;
1213 }
1214}
1215
8ce6284e 1216static int get_connections(struct sock *sk, u16 index)
2784eb41 1217{
2784eb41
JH
1218 struct mgmt_rp_get_connections *rp;
1219 struct hci_dev *hdev;
8035ded4 1220 struct hci_conn *c;
a38528f1 1221 size_t rp_len;
4e51eae9 1222 u16 count;
2784eb41
JH
1223 int i, err;
1224
1225 BT_DBG("");
1226
4e51eae9 1227 hdev = hci_dev_get(index);
2784eb41 1228 if (!hdev)
ca69b795
JH
1229 return cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS,
1230 MGMT_STATUS_INVALID_PARAMS);
2784eb41 1231
09fd0de5 1232 hci_dev_lock(hdev);
2784eb41
JH
1233
1234 count = 0;
b644ba33
JH
1235 list_for_each_entry(c, &hdev->conn_hash.list, list) {
1236 if (test_bit(HCI_CONN_MGMT_CONNECTED, &c->flags))
1237 count++;
2784eb41
JH
1238 }
1239
4c659c39 1240 rp_len = sizeof(*rp) + (count * sizeof(struct mgmt_addr_info));
a38528f1
JH
1241 rp = kmalloc(rp_len, GFP_ATOMIC);
1242 if (!rp) {
2784eb41
JH
1243 err = -ENOMEM;
1244 goto unlock;
1245 }
1246
2784eb41
JH
1247 put_unaligned_le16(count, &rp->conn_count);
1248
2784eb41 1249 i = 0;
4c659c39 1250 list_for_each_entry(c, &hdev->conn_hash.list, list) {
b644ba33
JH
1251 if (!test_bit(HCI_CONN_MGMT_CONNECTED, &c->flags))
1252 continue;
4c659c39 1253 bacpy(&rp->addr[i].bdaddr, &c->dst);
48264f06 1254 rp->addr[i].type = link_to_mgmt(c->type, c->dst_type);
4c659c39
JH
1255 if (rp->addr[i].type == MGMT_ADDR_INVALID)
1256 continue;
1257 i++;
1258 }
1259
1260 /* Recalculate length in case of filtered SCO connections, etc */
1261 rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info));
2784eb41 1262
4e51eae9 1263 err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len);
2784eb41
JH
1264
1265unlock:
a38528f1 1266 kfree(rp);
09fd0de5 1267 hci_dev_unlock(hdev);
2784eb41
JH
1268 hci_dev_put(hdev);
1269 return err;
1270}
1271
96d97a67
WR
1272static int send_pin_code_neg_reply(struct sock *sk, u16 index,
1273 struct hci_dev *hdev, struct mgmt_cp_pin_code_neg_reply *cp)
1274{
1275 struct pending_cmd *cmd;
1276 int err;
1277
2e58ef3e 1278 cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, hdev, cp,
96d97a67
WR
1279 sizeof(*cp));
1280 if (!cmd)
1281 return -ENOMEM;
1282
1283 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(cp->bdaddr),
1284 &cp->bdaddr);
1285 if (err < 0)
1286 mgmt_pending_remove(cmd);
1287
1288 return err;
1289}
1290
650f726d 1291static int pin_code_reply(struct sock *sk, u16 index, void *data, u16 len)
980e1a53
JH
1292{
1293 struct hci_dev *hdev;
96d97a67 1294 struct hci_conn *conn;
650f726d 1295 struct mgmt_cp_pin_code_reply *cp = data;
96d97a67 1296 struct mgmt_cp_pin_code_neg_reply ncp;
980e1a53 1297 struct hci_cp_pin_code_reply reply;
366a0336 1298 struct pending_cmd *cmd;
980e1a53
JH
1299 int err;
1300
1301 BT_DBG("");
1302
bdce7baf 1303 if (len != sizeof(*cp))
ca69b795
JH
1304 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1305 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1306
4e51eae9 1307 hdev = hci_dev_get(index);
980e1a53 1308 if (!hdev)
ca69b795
JH
1309 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1310 MGMT_STATUS_INVALID_PARAMS);
980e1a53 1311
09fd0de5 1312 hci_dev_lock(hdev);
980e1a53
JH
1313
1314 if (!test_bit(HCI_UP, &hdev->flags)) {
ca69b795
JH
1315 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1316 MGMT_STATUS_NOT_POWERED);
980e1a53
JH
1317 goto failed;
1318 }
1319
96d97a67
WR
1320 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1321 if (!conn) {
ca69b795
JH
1322 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
1323 MGMT_STATUS_NOT_CONNECTED);
96d97a67
WR
1324 goto failed;
1325 }
1326
1327 if (conn->pending_sec_level == BT_SECURITY_HIGH && cp->pin_len != 16) {
1328 bacpy(&ncp.bdaddr, &cp->bdaddr);
1329
1330 BT_ERR("PIN code is not 16 bytes long");
1331
1332 err = send_pin_code_neg_reply(sk, index, hdev, &ncp);
1333 if (err >= 0)
1334 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY,
ca69b795 1335 MGMT_STATUS_INVALID_PARAMS);
96d97a67
WR
1336
1337 goto failed;
1338 }
1339
650f726d
VCG
1340 cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, hdev, data,
1341 len);
366a0336
JH
1342 if (!cmd) {
1343 err = -ENOMEM;
980e1a53 1344 goto failed;
366a0336 1345 }
980e1a53
JH
1346
1347 bacpy(&reply.bdaddr, &cp->bdaddr);
1348 reply.pin_len = cp->pin_len;
24718ca5 1349 memcpy(reply.pin_code, cp->pin_code, sizeof(reply.pin_code));
980e1a53
JH
1350
1351 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_REPLY, sizeof(reply), &reply);
1352 if (err < 0)
a664b5bc 1353 mgmt_pending_remove(cmd);
980e1a53
JH
1354
1355failed:
09fd0de5 1356 hci_dev_unlock(hdev);
980e1a53
JH
1357 hci_dev_put(hdev);
1358
1359 return err;
1360}
1361
650f726d 1362static int pin_code_neg_reply(struct sock *sk, u16 index, void *data, u16 len)
980e1a53
JH
1363{
1364 struct hci_dev *hdev;
650f726d 1365 struct mgmt_cp_pin_code_neg_reply *cp = data;
980e1a53
JH
1366 int err;
1367
1368 BT_DBG("");
1369
bdce7baf
SJ
1370 if (len != sizeof(*cp))
1371 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
ca69b795 1372 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1373
4e51eae9 1374 hdev = hci_dev_get(index);
980e1a53 1375 if (!hdev)
4e51eae9 1376 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
ca69b795 1377 MGMT_STATUS_INVALID_PARAMS);
980e1a53 1378
09fd0de5 1379 hci_dev_lock(hdev);
980e1a53
JH
1380
1381 if (!test_bit(HCI_UP, &hdev->flags)) {
4e51eae9 1382 err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
ca69b795 1383 MGMT_STATUS_NOT_POWERED);
980e1a53
JH
1384 goto failed;
1385 }
1386
96d97a67 1387 err = send_pin_code_neg_reply(sk, index, hdev, cp);
980e1a53
JH
1388
1389failed:
09fd0de5 1390 hci_dev_unlock(hdev);
980e1a53
JH
1391 hci_dev_put(hdev);
1392
1393 return err;
1394}
1395
650f726d 1396static int set_io_capability(struct sock *sk, u16 index, void *data, u16 len)
17fa4b9d
JH
1397{
1398 struct hci_dev *hdev;
650f726d 1399 struct mgmt_cp_set_io_capability *cp = data;
17fa4b9d
JH
1400
1401 BT_DBG("");
1402
bdce7baf 1403 if (len != sizeof(*cp))
ca69b795
JH
1404 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY,
1405 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1406
4e51eae9 1407 hdev = hci_dev_get(index);
17fa4b9d 1408 if (!hdev)
ca69b795
JH
1409 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY,
1410 MGMT_STATUS_INVALID_PARAMS);
17fa4b9d 1411
09fd0de5 1412 hci_dev_lock(hdev);
17fa4b9d
JH
1413
1414 hdev->io_capability = cp->io_capability;
1415
1416 BT_DBG("%s IO capability set to 0x%02x", hdev->name,
b8534e0f 1417 hdev->io_capability);
17fa4b9d 1418
09fd0de5 1419 hci_dev_unlock(hdev);
17fa4b9d
JH
1420 hci_dev_put(hdev);
1421
4e51eae9 1422 return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, NULL, 0);
17fa4b9d
JH
1423}
1424
e9a416b5
JH
1425static inline struct pending_cmd *find_pairing(struct hci_conn *conn)
1426{
1427 struct hci_dev *hdev = conn->hdev;
8035ded4 1428 struct pending_cmd *cmd;
e9a416b5 1429
2e58ef3e 1430 list_for_each_entry(cmd, &hdev->mgmt_pending, list) {
e9a416b5
JH
1431 if (cmd->opcode != MGMT_OP_PAIR_DEVICE)
1432 continue;
1433
e9a416b5
JH
1434 if (cmd->user_data != conn)
1435 continue;
1436
1437 return cmd;
1438 }
1439
1440 return NULL;
1441}
1442
1443static void pairing_complete(struct pending_cmd *cmd, u8 status)
1444{
1445 struct mgmt_rp_pair_device rp;
1446 struct hci_conn *conn = cmd->user_data;
1447
ba4e564f
JH
1448 bacpy(&rp.addr.bdaddr, &conn->dst);
1449 rp.addr.type = link_to_mgmt(conn->type, conn->dst_type);
e9a416b5
JH
1450 rp.status = status;
1451
4e51eae9 1452 cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, &rp, sizeof(rp));
e9a416b5
JH
1453
1454 /* So we don't get further callbacks for this connection */
1455 conn->connect_cfm_cb = NULL;
1456 conn->security_cfm_cb = NULL;
1457 conn->disconn_cfm_cb = NULL;
1458
1459 hci_conn_put(conn);
1460
a664b5bc 1461 mgmt_pending_remove(cmd);
e9a416b5
JH
1462}
1463
1464static void pairing_complete_cb(struct hci_conn *conn, u8 status)
1465{
1466 struct pending_cmd *cmd;
1467
1468 BT_DBG("status %u", status);
1469
1470 cmd = find_pairing(conn);
56e5cb86 1471 if (!cmd)
e9a416b5 1472 BT_DBG("Unable to find a pending command");
56e5cb86
JH
1473 else
1474 pairing_complete(cmd, status);
e9a416b5
JH
1475}
1476
650f726d 1477static int pair_device(struct sock *sk, u16 index, void *data, u16 len)
e9a416b5
JH
1478{
1479 struct hci_dev *hdev;
650f726d 1480 struct mgmt_cp_pair_device *cp = data;
1425acb7 1481 struct mgmt_rp_pair_device rp;
e9a416b5
JH
1482 struct pending_cmd *cmd;
1483 u8 sec_level, auth_type;
1484 struct hci_conn *conn;
e9a416b5
JH
1485 int err;
1486
1487 BT_DBG("");
1488
bdce7baf 1489 if (len != sizeof(*cp))
ca69b795
JH
1490 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE,
1491 MGMT_STATUS_INVALID_PARAMS);
bdce7baf 1492
4e51eae9 1493 hdev = hci_dev_get(index);
e9a416b5 1494 if (!hdev)
ca69b795
JH
1495 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE,
1496 MGMT_STATUS_INVALID_PARAMS);
e9a416b5 1497
09fd0de5 1498 hci_dev_lock(hdev);
e9a416b5 1499
c908df36
VCG
1500 sec_level = BT_SECURITY_MEDIUM;
1501 if (cp->io_cap == 0x03)
e9a416b5 1502 auth_type = HCI_AT_DEDICATED_BONDING;
c908df36 1503 else
e9a416b5 1504 auth_type = HCI_AT_DEDICATED_BONDING_MITM;
e9a416b5 1505
ba4e564f
JH
1506 if (cp->addr.type == MGMT_ADDR_BREDR)
1507 conn = hci_connect(hdev, ACL_LINK, &cp->addr.bdaddr, sec_level,
7a512d01
VCG
1508 auth_type);
1509 else
ba4e564f 1510 conn = hci_connect(hdev, LE_LINK, &cp->addr.bdaddr, sec_level,
7a512d01
VCG
1511 auth_type);
1512
1425acb7
JH
1513 memset(&rp, 0, sizeof(rp));
1514 bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
1515 rp.addr.type = cp->addr.type;
1516
30e76272 1517 if (IS_ERR(conn)) {
1425acb7
JH
1518 rp.status = -PTR_ERR(conn);
1519 err = cmd_complete(sk, index, MGMT_OP_PAIR_DEVICE,
1520 &rp, sizeof(rp));
e9a416b5
JH
1521 goto unlock;
1522 }
1523
1524 if (conn->connect_cfm_cb) {
1525 hci_conn_put(conn);
1425acb7
JH
1526 rp.status = EBUSY;
1527 err = cmd_complete(sk, index, MGMT_OP_PAIR_DEVICE,
1528 &rp, sizeof(rp));
e9a416b5
JH
1529 goto unlock;
1530 }
1531
2e58ef3e 1532 cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, hdev, data, len);
e9a416b5
JH
1533 if (!cmd) {
1534 err = -ENOMEM;
1535 hci_conn_put(conn);
1536 goto unlock;
1537 }
1538
7a512d01 1539 /* For LE, just connecting isn't a proof that the pairing finished */
ba4e564f 1540 if (cp->addr.type == MGMT_ADDR_BREDR)
7a512d01
VCG
1541 conn->connect_cfm_cb = pairing_complete_cb;
1542
e9a416b5
JH
1543 conn->security_cfm_cb = pairing_complete_cb;
1544 conn->disconn_cfm_cb = pairing_complete_cb;
1545 conn->io_capability = cp->io_cap;
1546 cmd->user_data = conn;
1547
1548 if (conn->state == BT_CONNECTED &&
1549 hci_conn_security(conn, sec_level, auth_type))
1550 pairing_complete(cmd, 0);
1551
1552 err = 0;
1553
1554unlock:
09fd0de5 1555 hci_dev_unlock(hdev);
e9a416b5
JH
1556 hci_dev_put(hdev);
1557
1558 return err;
1559}
1560
28424707
JH
1561static int cancel_pair_device(struct sock *sk, u16 index,
1562 unsigned char *data, u16 len)
1563{
1564 struct mgmt_addr_info *addr = (void *) data;
1565 struct hci_dev *hdev;
1566 struct pending_cmd *cmd;
1567 struct hci_conn *conn;
1568 int err;
1569
1570 BT_DBG("");
1571
1572 if (len != sizeof(*addr))
1573 return cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
1574 MGMT_STATUS_INVALID_PARAMS);
1575
1576 hdev = hci_dev_get(index);
1577 if (!hdev)
1578 return cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
1579 MGMT_STATUS_INVALID_PARAMS);
1580
1581 hci_dev_lock(hdev);
1582
1583 cmd = mgmt_pending_find(MGMT_OP_PAIR_DEVICE, hdev);
1584 if (!cmd) {
1585 err = cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
1586 MGMT_STATUS_INVALID_PARAMS);
1587 goto unlock;
1588 }
1589
1590 conn = cmd->user_data;
1591
1592 if (bacmp(&addr->bdaddr, &conn->dst) != 0) {
1593 err = cmd_status(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE,
1594 MGMT_STATUS_INVALID_PARAMS);
1595 goto unlock;
1596 }
1597
1598 pairing_complete(cmd, MGMT_STATUS_CANCELLED);
1599
1600 err = cmd_complete(sk, index, MGMT_OP_CANCEL_PAIR_DEVICE, addr,
1601 sizeof(*addr));
1602unlock:
1603 hci_dev_unlock(hdev);
1604 hci_dev_put(hdev);
1605
1606 return err;
1607}
1608
0df4c185
BG
1609static int user_pairing_resp(struct sock *sk, u16 index, bdaddr_t *bdaddr,
1610 u16 mgmt_op, u16 hci_op, __le32 passkey)
a5c29683 1611{
a5c29683
JH
1612 struct pending_cmd *cmd;
1613 struct hci_dev *hdev;
0df4c185 1614 struct hci_conn *conn;
a5c29683
JH
1615 int err;
1616
4e51eae9 1617 hdev = hci_dev_get(index);
a5c29683 1618 if (!hdev)
ca69b795
JH
1619 return cmd_status(sk, index, mgmt_op,
1620 MGMT_STATUS_INVALID_PARAMS);
a5c29683 1621
09fd0de5 1622 hci_dev_lock(hdev);
08ba5382 1623
a5c29683 1624 if (!test_bit(HCI_UP, &hdev->flags)) {
0df4c185
BG
1625 err = cmd_status(sk, index, mgmt_op, MGMT_STATUS_NOT_POWERED);
1626 goto done;
a5c29683
JH
1627 }
1628
47c15e2b
BG
1629 /*
1630 * Check for an existing ACL link, if present pair via
1631 * HCI commands.
1632 *
1633 * If no ACL link is present, check for an LE link and if
1634 * present, pair via the SMP engine.
1635 *
1636 * If neither ACL nor LE links are present, fail with error.
1637 */
1638 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, bdaddr);
1639 if (!conn) {
1640 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr);
1641 if (!conn) {
1642 err = cmd_status(sk, index, mgmt_op,
1643 MGMT_STATUS_NOT_CONNECTED);
1644 goto done;
1645 }
1646
1647 /* Continue with pairing via SMP */
5fe57d9e
BG
1648 err = smp_user_confirm_reply(conn, mgmt_op, passkey);
1649
1650 if (!err)
1651 err = cmd_status(sk, index, mgmt_op,
1652 MGMT_STATUS_SUCCESS);
1653 else
1654 err = cmd_status(sk, index, mgmt_op,
1655 MGMT_STATUS_FAILED);
47c15e2b 1656
47c15e2b
BG
1657 goto done;
1658 }
1659
0df4c185 1660 cmd = mgmt_pending_add(sk, mgmt_op, hdev, bdaddr, sizeof(*bdaddr));
a5c29683
JH
1661 if (!cmd) {
1662 err = -ENOMEM;
0df4c185 1663 goto done;
a5c29683
JH
1664 }
1665
0df4c185 1666 /* Continue with pairing via HCI */
604086b7
BG
1667 if (hci_op == HCI_OP_USER_PASSKEY_REPLY) {
1668 struct hci_cp_user_passkey_reply cp;
1669
1670 bacpy(&cp.bdaddr, bdaddr);
1671 cp.passkey = passkey;
1672 err = hci_send_cmd(hdev, hci_op, sizeof(cp), &cp);
1673 } else
1674 err = hci_send_cmd(hdev, hci_op, sizeof(*bdaddr), bdaddr);
1675
a664b5bc
JH
1676 if (err < 0)
1677 mgmt_pending_remove(cmd);
a5c29683 1678
0df4c185 1679done:
09fd0de5 1680 hci_dev_unlock(hdev);
a5c29683
JH
1681 hci_dev_put(hdev);
1682
1683 return err;
1684}
1685
0df4c185
BG
1686static int user_confirm_reply(struct sock *sk, u16 index, void *data, u16 len)
1687{
650f726d 1688 struct mgmt_cp_user_confirm_reply *cp = data;
0df4c185
BG
1689
1690 BT_DBG("");
1691
1692 if (len != sizeof(*cp))
1693 return cmd_status(sk, index, MGMT_OP_USER_CONFIRM_REPLY,
1694 MGMT_STATUS_INVALID_PARAMS);
1695
1696 return user_pairing_resp(sk, index, &cp->bdaddr,
1697 MGMT_OP_USER_CONFIRM_REPLY,
1698 HCI_OP_USER_CONFIRM_REPLY, 0);
1699}
1700
1701static int user_confirm_neg_reply(struct sock *sk, u16 index, void *data,
1702 u16 len)
1703{
c9c2659f 1704 struct mgmt_cp_user_confirm_neg_reply *cp = data;
0df4c185
BG
1705
1706 BT_DBG("");
1707
1708 if (len != sizeof(*cp))
1709 return cmd_status(sk, index, MGMT_OP_USER_CONFIRM_NEG_REPLY,
1710 MGMT_STATUS_INVALID_PARAMS);
1711
1712 return user_pairing_resp(sk, index, &cp->bdaddr,
1713 MGMT_OP_USER_CONFIRM_NEG_REPLY,
1714 HCI_OP_USER_CONFIRM_NEG_REPLY, 0);
1715}
1716
604086b7
BG
1717static int user_passkey_reply(struct sock *sk, u16 index, void *data, u16 len)
1718{
650f726d 1719 struct mgmt_cp_user_passkey_reply *cp = data;
604086b7
BG
1720
1721 BT_DBG("");
1722
1723 if (len != sizeof(*cp))
1724 return cmd_status(sk, index, MGMT_OP_USER_PASSKEY_REPLY,
1725 EINVAL);
1726
1727 return user_pairing_resp(sk, index, &cp->bdaddr,
1728 MGMT_OP_USER_PASSKEY_REPLY,
1729 HCI_OP_USER_PASSKEY_REPLY, cp->passkey);
1730}
1731
1732static int user_passkey_neg_reply(struct sock *sk, u16 index, void *data,
1733 u16 len)
1734{
650f726d 1735 struct mgmt_cp_user_passkey_neg_reply *cp = data;
604086b7
BG
1736
1737 BT_DBG("");
1738
1739 if (len != sizeof(*cp))
1740 return cmd_status(sk, index, MGMT_OP_USER_PASSKEY_NEG_REPLY,
1741 EINVAL);
1742
1743 return user_pairing_resp(sk, index, &cp->bdaddr,
1744 MGMT_OP_USER_PASSKEY_NEG_REPLY,
1745 HCI_OP_USER_PASSKEY_NEG_REPLY, 0);
1746}
1747
650f726d 1748static int set_local_name(struct sock *sk, u16 index, void *data,
b312b161
JH
1749 u16 len)
1750{
650f726d 1751 struct mgmt_cp_set_local_name *mgmt_cp = data;
b312b161
JH
1752 struct hci_cp_write_local_name hci_cp;
1753 struct hci_dev *hdev;
1754 struct pending_cmd *cmd;
1755 int err;
1756
1757 BT_DBG("");
1758
1759 if (len != sizeof(*mgmt_cp))
ca69b795
JH
1760 return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME,
1761 MGMT_STATUS_INVALID_PARAMS);
b312b161
JH
1762
1763 hdev = hci_dev_get(index);
1764 if (!hdev)
ca69b795
JH
1765 return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME,
1766 MGMT_STATUS_INVALID_PARAMS);
b312b161 1767
09fd0de5 1768 hci_dev_lock(hdev);
b312b161 1769
650f726d
VCG
1770 cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, hdev, data,
1771 len);
b312b161
JH
1772 if (!cmd) {
1773 err = -ENOMEM;
1774 goto failed;
1775 }
1776
1777 memcpy(hci_cp.name, mgmt_cp->name, sizeof(hci_cp.name));
1778 err = hci_send_cmd(hdev, HCI_OP_WRITE_LOCAL_NAME, sizeof(hci_cp),
1779 &hci_cp);
1780 if (err < 0)
1781 mgmt_pending_remove(cmd);
1782
1783failed:
09fd0de5 1784 hci_dev_unlock(hdev);
b312b161
JH
1785 hci_dev_put(hdev);
1786
1787 return err;
1788}
1789
c35938b2
SJ
1790static int read_local_oob_data(struct sock *sk, u16 index)
1791{
1792 struct hci_dev *hdev;
1793 struct pending_cmd *cmd;
1794 int err;
1795
1796 BT_DBG("hci%u", index);
1797
1798 hdev = hci_dev_get(index);
1799 if (!hdev)
1800 return cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
ca69b795 1801 MGMT_STATUS_INVALID_PARAMS);
c35938b2 1802
09fd0de5 1803 hci_dev_lock(hdev);
c35938b2
SJ
1804
1805 if (!test_bit(HCI_UP, &hdev->flags)) {
1806 err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
ca69b795 1807 MGMT_STATUS_NOT_POWERED);
c35938b2
SJ
1808 goto unlock;
1809 }
1810
1811 if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) {
1812 err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
ca69b795 1813 MGMT_STATUS_NOT_SUPPORTED);
c35938b2
SJ
1814 goto unlock;
1815 }
1816
2e58ef3e 1817 if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev)) {
ca69b795
JH
1818 err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
1819 MGMT_STATUS_BUSY);
c35938b2
SJ
1820 goto unlock;
1821 }
1822
2e58ef3e 1823 cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, hdev, NULL, 0);
c35938b2
SJ
1824 if (!cmd) {
1825 err = -ENOMEM;
1826 goto unlock;
1827 }
1828
1829 err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
1830 if (err < 0)
1831 mgmt_pending_remove(cmd);
1832
1833unlock:
09fd0de5 1834 hci_dev_unlock(hdev);
c35938b2
SJ
1835 hci_dev_put(hdev);
1836
1837 return err;
1838}
1839
650f726d
VCG
1840static int add_remote_oob_data(struct sock *sk, u16 index, void *data,
1841 u16 len)
2763eda6
SJ
1842{
1843 struct hci_dev *hdev;
650f726d 1844 struct mgmt_cp_add_remote_oob_data *cp = data;
2763eda6
SJ
1845 int err;
1846
1847 BT_DBG("hci%u ", index);
1848
1849 if (len != sizeof(*cp))
1850 return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
ca69b795 1851 MGMT_STATUS_INVALID_PARAMS);
2763eda6
SJ
1852
1853 hdev = hci_dev_get(index);
1854 if (!hdev)
1855 return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
ca69b795 1856 MGMT_STATUS_INVALID_PARAMS);
2763eda6 1857
09fd0de5 1858 hci_dev_lock(hdev);
2763eda6
SJ
1859
1860 err = hci_add_remote_oob_data(hdev, &cp->bdaddr, cp->hash,
1861 cp->randomizer);
1862 if (err < 0)
ca69b795
JH
1863 err = cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
1864 MGMT_STATUS_FAILED);
2763eda6
SJ
1865 else
1866 err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, NULL,
1867 0);
1868
09fd0de5 1869 hci_dev_unlock(hdev);
2763eda6
SJ
1870 hci_dev_put(hdev);
1871
1872 return err;
1873}
1874
1875static int remove_remote_oob_data(struct sock *sk, u16 index,
650f726d 1876 void *data, u16 len)
2763eda6
SJ
1877{
1878 struct hci_dev *hdev;
650f726d 1879 struct mgmt_cp_remove_remote_oob_data *cp = data;
2763eda6
SJ
1880 int err;
1881
1882 BT_DBG("hci%u ", index);
1883
1884 if (len != sizeof(*cp))
1885 return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
ca69b795 1886 MGMT_STATUS_INVALID_PARAMS);
2763eda6
SJ
1887
1888 hdev = hci_dev_get(index);
1889 if (!hdev)
1890 return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
ca69b795 1891 MGMT_STATUS_INVALID_PARAMS);
2763eda6 1892
09fd0de5 1893 hci_dev_lock(hdev);
2763eda6
SJ
1894
1895 err = hci_remove_remote_oob_data(hdev, &cp->bdaddr);
1896 if (err < 0)
1897 err = cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
ca69b795 1898 MGMT_STATUS_INVALID_PARAMS);
2763eda6
SJ
1899 else
1900 err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
1901 NULL, 0);
1902
09fd0de5 1903 hci_dev_unlock(hdev);
2763eda6
SJ
1904 hci_dev_put(hdev);
1905
1906 return err;
1907}
1908
450dfdaf 1909static int start_discovery(struct sock *sk, u16 index,
650f726d 1910 void *data, u16 len)
14a53664 1911{
650f726d 1912 struct mgmt_cp_start_discovery *cp = data;
14a53664
JH
1913 struct pending_cmd *cmd;
1914 struct hci_dev *hdev;
1915 int err;
1916
1917 BT_DBG("hci%u", index);
1918
450dfdaf
JH
1919 if (len != sizeof(*cp))
1920 return cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
1921 MGMT_STATUS_INVALID_PARAMS);
1922
14a53664
JH
1923 hdev = hci_dev_get(index);
1924 if (!hdev)
ca69b795
JH
1925 return cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
1926 MGMT_STATUS_INVALID_PARAMS);
14a53664 1927
09fd0de5 1928 hci_dev_lock(hdev);
14a53664 1929
bd2d1334 1930 if (!test_bit(HCI_UP, &hdev->flags)) {
ca69b795
JH
1931 err = cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
1932 MGMT_STATUS_NOT_POWERED);
bd2d1334
JH
1933 goto failed;
1934 }
1935
ff9ef578
JH
1936 if (hdev->discovery.state != DISCOVERY_STOPPED) {
1937 err = cmd_status(sk, index, MGMT_OP_START_DISCOVERY,
1938 MGMT_STATUS_BUSY);
1939 goto failed;
1940 }
1941
2e58ef3e 1942 cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, hdev, NULL, 0);
14a53664
JH
1943 if (!cmd) {
1944 err = -ENOMEM;
1945 goto failed;
1946 }
1947
2519a1fc 1948 err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR);
14a53664
JH
1949 if (err < 0)
1950 mgmt_pending_remove(cmd);
ff9ef578
JH
1951 else
1952 hci_discovery_set_state(hdev, DISCOVERY_STARTING);
14a53664
JH
1953
1954failed:
09fd0de5 1955 hci_dev_unlock(hdev);
14a53664
JH
1956 hci_dev_put(hdev);
1957
1958 return err;
1959}
1960
1961static int stop_discovery(struct sock *sk, u16 index)
1962{
1963 struct hci_dev *hdev;
1964 struct pending_cmd *cmd;
30dc78e1
JH
1965 struct hci_cp_remote_name_req_cancel cp;
1966 struct inquiry_entry *e;
14a53664
JH
1967 int err;
1968
1969 BT_DBG("hci%u", index);
1970
1971 hdev = hci_dev_get(index);
1972 if (!hdev)
ca69b795
JH
1973 return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY,
1974 MGMT_STATUS_INVALID_PARAMS);
14a53664 1975
09fd0de5 1976 hci_dev_lock(hdev);
14a53664 1977
30dc78e1 1978 if (!hci_discovery_active(hdev)) {
ff9ef578
JH
1979 err = cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY,
1980 MGMT_STATUS_REJECTED);
30dc78e1 1981 goto unlock;
ff9ef578
JH
1982 }
1983
2e58ef3e 1984 cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, NULL, 0);
14a53664
JH
1985 if (!cmd) {
1986 err = -ENOMEM;
30dc78e1
JH
1987 goto unlock;
1988 }
1989
1990 if (hdev->discovery.state == DISCOVERY_INQUIRY) {
1991 err = hci_cancel_inquiry(hdev);
1992 if (err < 0)
1993 mgmt_pending_remove(cmd);
1994 else
1995 hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
1996 goto unlock;
1997 }
1998
1999 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_PENDING);
2000 if (!e) {
2001 mgmt_pending_remove(cmd);
2002 err = cmd_complete(sk, index, MGMT_OP_STOP_DISCOVERY, NULL, 0);
2003 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
2004 goto unlock;
14a53664
JH
2005 }
2006
30dc78e1
JH
2007 bacpy(&cp.bdaddr, &e->data.bdaddr);
2008 err = hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ_CANCEL,
2009 sizeof(cp), &cp);
14a53664
JH
2010 if (err < 0)
2011 mgmt_pending_remove(cmd);
ff9ef578
JH
2012 else
2013 hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
14a53664 2014
30dc78e1 2015unlock:
09fd0de5 2016 hci_dev_unlock(hdev);
14a53664
JH
2017 hci_dev_put(hdev);
2018
2019 return err;
2020}
2021
650f726d 2022static int confirm_name(struct sock *sk, u16 index, void *data, u16 len)
561aafbc 2023{
650f726d 2024 struct mgmt_cp_confirm_name *cp = data;
561aafbc
JH
2025 struct inquiry_entry *e;
2026 struct hci_dev *hdev;
2027 int err;
2028
2029 BT_DBG("hci%u", index);
2030
2031 if (len != sizeof(*cp))
2032 return cmd_status(sk, index, MGMT_OP_CONFIRM_NAME,
2033 MGMT_STATUS_INVALID_PARAMS);
2034
2035 hdev = hci_dev_get(index);
2036 if (!hdev)
2037 return cmd_status(sk, index, MGMT_OP_CONFIRM_NAME,
2038 MGMT_STATUS_INVALID_PARAMS);
2039
2040 hci_dev_lock(hdev);
2041
30dc78e1
JH
2042 if (!hci_discovery_active(hdev)) {
2043 err = cmd_status(sk, index, MGMT_OP_CONFIRM_NAME,
2044 MGMT_STATUS_FAILED);
2045 goto failed;
2046 }
2047
561aafbc
JH
2048 e = hci_inquiry_cache_lookup_unknown(hdev, &cp->bdaddr);
2049 if (!e) {
2050 err = cmd_status (sk, index, MGMT_OP_CONFIRM_NAME,
2051 MGMT_STATUS_INVALID_PARAMS);
2052 goto failed;
2053 }
2054
2055 if (cp->name_known) {
2056 e->name_state = NAME_KNOWN;
2057 list_del(&e->list);
2058 } else {
2059 e->name_state = NAME_NEEDED;
a3d4e20a 2060 hci_inquiry_cache_update_resolve(hdev, e);
561aafbc
JH
2061 }
2062
2063 err = 0;
2064
2065failed:
2066 hci_dev_unlock(hdev);
2067
2068 return err;
2069}
2070
650f726d 2071static int block_device(struct sock *sk, u16 index, void *data, u16 len)
7fbec224
AJ
2072{
2073 struct hci_dev *hdev;
650f726d 2074 struct mgmt_cp_block_device *cp = data;
7fbec224
AJ
2075 int err;
2076
2077 BT_DBG("hci%u", index);
2078
7fbec224
AJ
2079 if (len != sizeof(*cp))
2080 return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
ca69b795 2081 MGMT_STATUS_INVALID_PARAMS);
7fbec224
AJ
2082
2083 hdev = hci_dev_get(index);
2084 if (!hdev)
2085 return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
ca69b795 2086 MGMT_STATUS_INVALID_PARAMS);
7fbec224 2087
09fd0de5 2088 hci_dev_lock(hdev);
5e762444 2089
7fbec224 2090 err = hci_blacklist_add(hdev, &cp->bdaddr);
7fbec224 2091 if (err < 0)
ca69b795
JH
2092 err = cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE,
2093 MGMT_STATUS_FAILED);
7fbec224
AJ
2094 else
2095 err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE,
2096 NULL, 0);
5e762444 2097
09fd0de5 2098 hci_dev_unlock(hdev);
7fbec224
AJ
2099 hci_dev_put(hdev);
2100
2101 return err;
2102}
2103
650f726d 2104static int unblock_device(struct sock *sk, u16 index, void *data, u16 len)
7fbec224
AJ
2105{
2106 struct hci_dev *hdev;
650f726d 2107 struct mgmt_cp_unblock_device *cp = data;
7fbec224
AJ
2108 int err;
2109
2110 BT_DBG("hci%u", index);
2111
7fbec224
AJ
2112 if (len != sizeof(*cp))
2113 return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
ca69b795 2114 MGMT_STATUS_INVALID_PARAMS);
7fbec224
AJ
2115
2116 hdev = hci_dev_get(index);
2117 if (!hdev)
2118 return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
ca69b795 2119 MGMT_STATUS_INVALID_PARAMS);
7fbec224 2120
09fd0de5 2121 hci_dev_lock(hdev);
5e762444 2122
7fbec224
AJ
2123 err = hci_blacklist_del(hdev, &cp->bdaddr);
2124
2125 if (err < 0)
ca69b795
JH
2126 err = cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE,
2127 MGMT_STATUS_INVALID_PARAMS);
7fbec224
AJ
2128 else
2129 err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE,
2130 NULL, 0);
5e762444 2131
09fd0de5 2132 hci_dev_unlock(hdev);
7fbec224
AJ
2133 hci_dev_put(hdev);
2134
2135 return err;
2136}
2137
f6422ec6 2138static int set_fast_connectable(struct sock *sk, u16 index,
650f726d 2139 void *data, u16 len)
f6422ec6
AJ
2140{
2141 struct hci_dev *hdev;
650f726d 2142 struct mgmt_mode *cp = data;
f6422ec6
AJ
2143 struct hci_cp_write_page_scan_activity acp;
2144 u8 type;
2145 int err;
2146
2147 BT_DBG("hci%u", index);
2148
2149 if (len != sizeof(*cp))
2150 return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2151 MGMT_STATUS_INVALID_PARAMS);
f6422ec6
AJ
2152
2153 hdev = hci_dev_get(index);
2154 if (!hdev)
2155 return cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2156 MGMT_STATUS_INVALID_PARAMS);
f6422ec6
AJ
2157
2158 hci_dev_lock(hdev);
2159
f7c6869c 2160 if (cp->val) {
f6422ec6
AJ
2161 type = PAGE_SCAN_TYPE_INTERLACED;
2162 acp.interval = 0x0024; /* 22.5 msec page scan interval */
2163 } else {
2164 type = PAGE_SCAN_TYPE_STANDARD; /* default */
2165 acp.interval = 0x0800; /* default 1.28 sec page scan */
2166 }
2167
2168 acp.window = 0x0012; /* default 11.25 msec page scan window */
2169
2170 err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY,
2171 sizeof(acp), &acp);
2172 if (err < 0) {
2173 err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2174 MGMT_STATUS_FAILED);
f6422ec6
AJ
2175 goto done;
2176 }
2177
2178 err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type);
2179 if (err < 0) {
2180 err = cmd_status(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
ca69b795 2181 MGMT_STATUS_FAILED);
f6422ec6
AJ
2182 goto done;
2183 }
2184
2185 err = cmd_complete(sk, index, MGMT_OP_SET_FAST_CONNECTABLE,
2186 NULL, 0);
2187done:
2188 hci_dev_unlock(hdev);
2189 hci_dev_put(hdev);
2190
2191 return err;
2192}
2193
346af67b
VCG
2194static int load_long_term_keys(struct sock *sk, u16 index,
2195 void *cp_data, u16 len)
2196{
2197 struct hci_dev *hdev;
2198 struct mgmt_cp_load_long_term_keys *cp = cp_data;
2199 u16 key_count, expected_len;
2200 int i;
2201
2202 if (len < sizeof(*cp))
2203 return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS,
2204 EINVAL);
2205
2206 key_count = get_unaligned_le16(&cp->key_count);
2207
2208 expected_len = sizeof(*cp) + key_count *
2209 sizeof(struct mgmt_ltk_info);
2210 if (expected_len != len) {
2211 BT_ERR("load_keys: expected %u bytes, got %u bytes",
2212 len, expected_len);
2213 return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS,
2214 EINVAL);
2215 }
2216
2217 hdev = hci_dev_get(index);
2218 if (!hdev)
2219 return cmd_status(sk, index, MGMT_OP_LOAD_LONG_TERM_KEYS,
2220 ENODEV);
2221
2222 BT_DBG("hci%u key_count %u", index, key_count);
2223
2224 hci_dev_lock(hdev);
2225
2226 hci_smp_ltks_clear(hdev);
2227
2228 for (i = 0; i < key_count; i++) {
2229 struct mgmt_ltk_info *key = &cp->keys[i];
2230 u8 type;
2231
2232 if (key->master)
2233 type = HCI_SMP_LTK;
2234 else
2235 type = HCI_SMP_LTK_SLAVE;
2236
2237 hci_add_ltk(hdev, &key->addr.bdaddr, key->addr.type,
2238 type, 0, key->authenticated, key->val,
2239 key->enc_size, key->ediv, key->rand);
2240 }
2241
2242 hci_dev_unlock(hdev);
2243 hci_dev_put(hdev);
2244
2245 return 0;
2246}
2247
0381101f
JH
2248int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
2249{
650f726d
VCG
2250 void *buf;
2251 u8 *cp;
0381101f 2252 struct mgmt_hdr *hdr;
4e51eae9 2253 u16 opcode, index, len;
0381101f
JH
2254 int err;
2255
2256 BT_DBG("got %zu bytes", msglen);
2257
2258 if (msglen < sizeof(*hdr))
2259 return -EINVAL;
2260
e63a15ec 2261 buf = kmalloc(msglen, GFP_KERNEL);
0381101f
JH
2262 if (!buf)
2263 return -ENOMEM;
2264
2265 if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
2266 err = -EFAULT;
2267 goto done;
2268 }
2269
650f726d 2270 hdr = buf;
0381101f 2271 opcode = get_unaligned_le16(&hdr->opcode);
4e51eae9 2272 index = get_unaligned_le16(&hdr->index);
0381101f
JH
2273 len = get_unaligned_le16(&hdr->len);
2274
2275 if (len != msglen - sizeof(*hdr)) {
2276 err = -EINVAL;
2277 goto done;
2278 }
2279
650f726d
VCG
2280 cp = buf + sizeof(*hdr);
2281
0381101f 2282 switch (opcode) {
02d98129
JH
2283 case MGMT_OP_READ_VERSION:
2284 err = read_version(sk);
2285 break;
faba42eb
JH
2286 case MGMT_OP_READ_INDEX_LIST:
2287 err = read_index_list(sk);
2288 break;
f7b64e69 2289 case MGMT_OP_READ_INFO:
4e51eae9 2290 err = read_controller_info(sk, index);
f7b64e69 2291 break;
eec8d2bc 2292 case MGMT_OP_SET_POWERED:
650f726d 2293 err = set_powered(sk, index, cp, len);
eec8d2bc 2294 break;
73f22f62 2295 case MGMT_OP_SET_DISCOVERABLE:
650f726d 2296 err = set_discoverable(sk, index, cp, len);
73f22f62 2297 break;
9fbcbb45 2298 case MGMT_OP_SET_CONNECTABLE:
650f726d 2299 err = set_connectable(sk, index, cp, len);
9fbcbb45 2300 break;
f7c6869c 2301 case MGMT_OP_SET_FAST_CONNECTABLE:
650f726d 2302 err = set_fast_connectable(sk, index, cp, len);
f7c6869c 2303 break;
c542a06c 2304 case MGMT_OP_SET_PAIRABLE:
650f726d 2305 err = set_pairable(sk, index, cp, len);
c542a06c 2306 break;
2aeb9a1a 2307 case MGMT_OP_ADD_UUID:
650f726d 2308 err = add_uuid(sk, index, cp, len);
2aeb9a1a
JH
2309 break;
2310 case MGMT_OP_REMOVE_UUID:
650f726d 2311 err = remove_uuid(sk, index, cp, len);
2aeb9a1a 2312 break;
1aff6f09 2313 case MGMT_OP_SET_DEV_CLASS:
650f726d 2314 err = set_dev_class(sk, index, cp, len);
1aff6f09 2315 break;
86742e1e 2316 case MGMT_OP_LOAD_LINK_KEYS:
650f726d 2317 err = load_link_keys(sk, index, cp, len);
55ed8ca1 2318 break;
86742e1e 2319 case MGMT_OP_REMOVE_KEYS:
650f726d 2320 err = remove_keys(sk, index, cp, len);
55ed8ca1 2321 break;
8962ee74 2322 case MGMT_OP_DISCONNECT:
650f726d 2323 err = disconnect(sk, index, cp, len);
8962ee74 2324 break;
2784eb41 2325 case MGMT_OP_GET_CONNECTIONS:
8ce6284e 2326 err = get_connections(sk, index);
2784eb41 2327 break;
980e1a53 2328 case MGMT_OP_PIN_CODE_REPLY:
650f726d 2329 err = pin_code_reply(sk, index, cp, len);
980e1a53
JH
2330 break;
2331 case MGMT_OP_PIN_CODE_NEG_REPLY:
650f726d 2332 err = pin_code_neg_reply(sk, index, cp, len);
980e1a53 2333 break;
17fa4b9d 2334 case MGMT_OP_SET_IO_CAPABILITY:
650f726d 2335 err = set_io_capability(sk, index, cp, len);
17fa4b9d 2336 break;
e9a416b5 2337 case MGMT_OP_PAIR_DEVICE:
650f726d 2338 err = pair_device(sk, index, cp, len);
e9a416b5 2339 break;
28424707
JH
2340 case MGMT_OP_CANCEL_PAIR_DEVICE:
2341 err = cancel_pair_device(sk, index, buf + sizeof(*hdr), len);
2342 break;
a5c29683 2343 case MGMT_OP_USER_CONFIRM_REPLY:
650f726d 2344 err = user_confirm_reply(sk, index, cp, len);
a5c29683
JH
2345 break;
2346 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
650f726d 2347 err = user_confirm_neg_reply(sk, index, cp, len);
a5c29683 2348 break;
604086b7 2349 case MGMT_OP_USER_PASSKEY_REPLY:
650f726d 2350 err = user_passkey_reply(sk, index, cp, len);
604086b7
BG
2351 break;
2352 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
650f726d 2353 err = user_passkey_neg_reply(sk, index, cp, len);
a5c29683 2354 break;
b312b161 2355 case MGMT_OP_SET_LOCAL_NAME:
650f726d 2356 err = set_local_name(sk, index, cp, len);
b312b161 2357 break;
c35938b2
SJ
2358 case MGMT_OP_READ_LOCAL_OOB_DATA:
2359 err = read_local_oob_data(sk, index);
2360 break;
2763eda6 2361 case MGMT_OP_ADD_REMOTE_OOB_DATA:
650f726d 2362 err = add_remote_oob_data(sk, index, cp, len);
2763eda6
SJ
2363 break;
2364 case MGMT_OP_REMOVE_REMOTE_OOB_DATA:
650f726d 2365 err = remove_remote_oob_data(sk, index, cp, len);
2763eda6 2366 break;
14a53664 2367 case MGMT_OP_START_DISCOVERY:
650f726d 2368 err = start_discovery(sk, index, cp, len);
14a53664
JH
2369 break;
2370 case MGMT_OP_STOP_DISCOVERY:
2371 err = stop_discovery(sk, index);
2372 break;
561aafbc 2373 case MGMT_OP_CONFIRM_NAME:
650f726d 2374 err = confirm_name(sk, index, cp, len);
561aafbc 2375 break;
7fbec224 2376 case MGMT_OP_BLOCK_DEVICE:
650f726d 2377 err = block_device(sk, index, cp, len);
7fbec224
AJ
2378 break;
2379 case MGMT_OP_UNBLOCK_DEVICE:
650f726d 2380 err = unblock_device(sk, index, cp, len);
7fbec224 2381 break;
346af67b
VCG
2382 case MGMT_OP_LOAD_LONG_TERM_KEYS:
2383 err = load_long_term_keys(sk, index, cp, len);
2384 break;
0381101f
JH
2385 default:
2386 BT_DBG("Unknown op %u", opcode);
ca69b795
JH
2387 err = cmd_status(sk, index, opcode,
2388 MGMT_STATUS_UNKNOWN_COMMAND);
0381101f
JH
2389 break;
2390 }
2391
e41d8b4e
JH
2392 if (err < 0)
2393 goto done;
2394
0381101f
JH
2395 err = msglen;
2396
2397done:
2398 kfree(buf);
2399 return err;
2400}
c71e97bf 2401
b24752fe
JH
2402static void cmd_status_rsp(struct pending_cmd *cmd, void *data)
2403{
2404 u8 *status = data;
2405
2406 cmd_status(cmd->sk, cmd->index, cmd->opcode, *status);
2407 mgmt_pending_remove(cmd);
2408}
2409
744cf19e 2410int mgmt_index_added(struct hci_dev *hdev)
c71e97bf 2411{
744cf19e 2412 return mgmt_event(MGMT_EV_INDEX_ADDED, hdev, NULL, 0, NULL);
c71e97bf
JH
2413}
2414
744cf19e 2415int mgmt_index_removed(struct hci_dev *hdev)
c71e97bf 2416{
b24752fe
JH
2417 u8 status = ENODEV;
2418
744cf19e 2419 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
b24752fe 2420
744cf19e 2421 return mgmt_event(MGMT_EV_INDEX_REMOVED, hdev, NULL, 0, NULL);
eec8d2bc
JH
2422}
2423
73f22f62 2424struct cmd_lookup {
72a734ec 2425 u8 val;
eec8d2bc 2426 struct sock *sk;
69ab39ea 2427 struct hci_dev *hdev;
eec8d2bc
JH
2428};
2429
69ab39ea 2430static void settings_rsp(struct pending_cmd *cmd, void *data)
eec8d2bc 2431{
73f22f62 2432 struct cmd_lookup *match = data;
eec8d2bc 2433
69ab39ea 2434 send_settings_rsp(cmd->sk, cmd->opcode, match->hdev);
eec8d2bc
JH
2435
2436 list_del(&cmd->list);
2437
2438 if (match->sk == NULL) {
2439 match->sk = cmd->sk;
2440 sock_hold(match->sk);
2441 }
2442
2443 mgmt_pending_free(cmd);
c71e97bf 2444}
5add6af8 2445
744cf19e 2446int mgmt_powered(struct hci_dev *hdev, u8 powered)
5add6af8 2447{
69ab39ea
JH
2448 struct cmd_lookup match = { powered, NULL, hdev };
2449 __le32 ev;
eec8d2bc 2450 int ret;
5add6af8 2451
69ab39ea 2452 mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
5add6af8 2453
b24752fe
JH
2454 if (!powered) {
2455 u8 status = ENETDOWN;
744cf19e 2456 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
b24752fe
JH
2457 }
2458
69ab39ea 2459 ev = cpu_to_le32(get_current_settings(hdev));
eec8d2bc 2460
69ab39ea
JH
2461 ret = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev),
2462 match.sk);
eec8d2bc
JH
2463
2464 if (match.sk)
2465 sock_put(match.sk);
2466
2467 return ret;
5add6af8 2468}
73f22f62 2469
744cf19e 2470int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
73f22f62 2471{
69ab39ea
JH
2472 struct cmd_lookup match = { discoverable, NULL, hdev };
2473 __le32 ev;
73f22f62
JH
2474 int ret;
2475
69ab39ea 2476 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, settings_rsp, &match);
72a734ec 2477
69ab39ea 2478 ev = cpu_to_le32(get_current_settings(hdev));
73f22f62 2479
69ab39ea 2480 ret = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev),
4e51eae9 2481 match.sk);
73f22f62
JH
2482 if (match.sk)
2483 sock_put(match.sk);
2484
2485 return ret;
2486}
9fbcbb45 2487
744cf19e 2488int mgmt_connectable(struct hci_dev *hdev, u8 connectable)
9fbcbb45 2489{
69ab39ea
JH
2490 __le32 ev;
2491 struct cmd_lookup match = { connectable, NULL, hdev };
9fbcbb45
JH
2492 int ret;
2493
69ab39ea
JH
2494 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, settings_rsp,
2495 &match);
9fbcbb45 2496
69ab39ea 2497 ev = cpu_to_le32(get_current_settings(hdev));
9fbcbb45 2498
69ab39ea 2499 ret = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), match.sk);
9fbcbb45
JH
2500
2501 if (match.sk)
2502 sock_put(match.sk);
2503
2504 return ret;
2505}
55ed8ca1 2506
744cf19e 2507int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status)
2d7cee58 2508{
ca69b795
JH
2509 u8 mgmt_err = mgmt_status(status);
2510
2d7cee58 2511 if (scan & SCAN_PAGE)
744cf19e 2512 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev,
ca69b795 2513 cmd_status_rsp, &mgmt_err);
2d7cee58
JH
2514
2515 if (scan & SCAN_INQUIRY)
744cf19e 2516 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev,
ca69b795 2517 cmd_status_rsp, &mgmt_err);
2d7cee58
JH
2518
2519 return 0;
2520}
2521
744cf19e
JH
2522int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
2523 u8 persistent)
55ed8ca1 2524{
86742e1e 2525 struct mgmt_ev_new_link_key ev;
55ed8ca1 2526
a492cd52 2527 memset(&ev, 0, sizeof(ev));
55ed8ca1 2528
a492cd52
VCG
2529 ev.store_hint = persistent;
2530 bacpy(&ev.key.bdaddr, &key->bdaddr);
2531 ev.key.type = key->type;
2532 memcpy(ev.key.val, key->val, 16);
2533 ev.key.pin_len = key->pin_len;
55ed8ca1 2534
744cf19e 2535 return mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL);
55ed8ca1 2536}
f7520543 2537
346af67b
VCG
2538int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent)
2539{
2540 struct mgmt_ev_new_long_term_key ev;
2541
2542 memset(&ev, 0, sizeof(ev));
2543
2544 ev.store_hint = persistent;
2545 bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
2546 ev.key.addr.type = key->bdaddr_type;
2547 ev.key.authenticated = key->authenticated;
2548 ev.key.enc_size = key->enc_size;
2549 ev.key.ediv = key->ediv;
2550
2551 if (key->type == HCI_SMP_LTK)
2552 ev.key.master = 1;
2553
2554 memcpy(ev.key.rand, key->rand, sizeof(key->rand));
2555 memcpy(ev.key.val, key->val, sizeof(key->val));
2556
2557 return mgmt_event(MGMT_EV_NEW_LONG_TERM_KEY, hdev,
2558 &ev, sizeof(ev), NULL);
2559}
2560
afc747a6 2561int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
b644ba33
JH
2562 u8 addr_type, u8 *name, u8 name_len,
2563 u8 *dev_class)
f7520543 2564{
b644ba33
JH
2565 char buf[512];
2566 struct mgmt_ev_device_connected *ev = (void *) buf;
2567 u16 eir_len = 0;
f7520543 2568
b644ba33
JH
2569 bacpy(&ev->addr.bdaddr, bdaddr);
2570 ev->addr.type = link_to_mgmt(link_type, addr_type);
f7520543 2571
b644ba33
JH
2572 if (name_len > 0)
2573 eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE,
2574 name, name_len);
2575
2576 if (dev_class && memcmp(dev_class, "\0\0\0", 3) != 0)
2577 eir_len = eir_append_data(&ev->eir[eir_len], eir_len,
2578 EIR_CLASS_OF_DEV, dev_class, 3);
2579
2580 put_unaligned_le16(eir_len, &ev->eir_len);
2581
2582 return mgmt_event(MGMT_EV_DEVICE_CONNECTED, hdev, buf,
2583 sizeof(*ev) + eir_len, NULL);
f7520543
JH
2584}
2585
8962ee74
JH
2586static void disconnect_rsp(struct pending_cmd *cmd, void *data)
2587{
c68fb7ff 2588 struct mgmt_cp_disconnect *cp = cmd->param;
8962ee74 2589 struct sock **sk = data;
a38528f1 2590 struct mgmt_rp_disconnect rp;
8962ee74 2591
a38528f1 2592 bacpy(&rp.bdaddr, &cp->bdaddr);
37d9ef76 2593 rp.status = 0;
8962ee74 2594
4e51eae9 2595 cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, &rp, sizeof(rp));
8962ee74
JH
2596
2597 *sk = cmd->sk;
2598 sock_hold(*sk);
2599
a664b5bc 2600 mgmt_pending_remove(cmd);
8962ee74
JH
2601}
2602
a8a1d19e
JH
2603static void remove_keys_rsp(struct pending_cmd *cmd, void *data)
2604{
2605 u8 *status = data;
2606 struct mgmt_cp_remove_keys *cp = cmd->param;
2607 struct mgmt_rp_remove_keys rp;
2608
2609 memset(&rp, 0, sizeof(rp));
2610 bacpy(&rp.bdaddr, &cp->bdaddr);
2611 if (status != NULL)
2612 rp.status = *status;
2613
2614 cmd_complete(cmd->sk, cmd->index, MGMT_OP_REMOVE_KEYS, &rp,
2615 sizeof(rp));
2616
2617 mgmt_pending_remove(cmd);
2618}
2619
afc747a6
JH
2620int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
2621 u8 link_type, u8 addr_type)
f7520543 2622{
4c659c39 2623 struct mgmt_addr_info ev;
8962ee74
JH
2624 struct sock *sk = NULL;
2625 int err;
2626
744cf19e 2627 mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk);
f7520543 2628
f7520543 2629 bacpy(&ev.bdaddr, bdaddr);
48264f06 2630 ev.type = link_to_mgmt(link_type, addr_type);
f7520543 2631
afc747a6
JH
2632 err = mgmt_event(MGMT_EV_DEVICE_DISCONNECTED, hdev, &ev, sizeof(ev),
2633 sk);
8962ee74
JH
2634
2635 if (sk)
2636 sock_put(sk);
2637
a8a1d19e
JH
2638 mgmt_pending_foreach(MGMT_OP_REMOVE_KEYS, hdev, remove_keys_rsp, NULL);
2639
8962ee74
JH
2640 return err;
2641}
2642
37d9ef76 2643int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status)
8962ee74
JH
2644{
2645 struct pending_cmd *cmd;
ca69b795 2646 u8 mgmt_err = mgmt_status(status);
8962ee74
JH
2647 int err;
2648
2e58ef3e 2649 cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, hdev);
8962ee74
JH
2650 if (!cmd)
2651 return -ENOENT;
2652
37d9ef76
JH
2653 if (bdaddr) {
2654 struct mgmt_rp_disconnect rp;
2655
2656 bacpy(&rp.bdaddr, bdaddr);
2657 rp.status = status;
2658
2659 err = cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT,
2660 &rp, sizeof(rp));
2661 } else
2662 err = cmd_status(cmd->sk, hdev->id, MGMT_OP_DISCONNECT,
ca69b795 2663 mgmt_err);
8962ee74 2664
a664b5bc 2665 mgmt_pending_remove(cmd);
8962ee74
JH
2666
2667 return err;
f7520543 2668}
17d5c04c 2669
48264f06
JH
2670int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
2671 u8 addr_type, u8 status)
17d5c04c
JH
2672{
2673 struct mgmt_ev_connect_failed ev;
2674
4c659c39 2675 bacpy(&ev.addr.bdaddr, bdaddr);
48264f06 2676 ev.addr.type = link_to_mgmt(link_type, addr_type);
ca69b795 2677 ev.status = mgmt_status(status);
17d5c04c 2678
744cf19e 2679 return mgmt_event(MGMT_EV_CONNECT_FAILED, hdev, &ev, sizeof(ev), NULL);
17d5c04c 2680}
980e1a53 2681
744cf19e 2682int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure)
980e1a53
JH
2683{
2684 struct mgmt_ev_pin_code_request ev;
2685
980e1a53 2686 bacpy(&ev.bdaddr, bdaddr);
a770bb5a 2687 ev.secure = secure;
980e1a53 2688
744cf19e 2689 return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, hdev, &ev, sizeof(ev),
4e51eae9 2690 NULL);
980e1a53
JH
2691}
2692
744cf19e
JH
2693int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
2694 u8 status)
980e1a53
JH
2695{
2696 struct pending_cmd *cmd;
ac56fb13 2697 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
2698 int err;
2699
2e58ef3e 2700 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, hdev);
980e1a53
JH
2701 if (!cmd)
2702 return -ENOENT;
2703
ac56fb13 2704 bacpy(&rp.bdaddr, bdaddr);
ca69b795 2705 rp.status = mgmt_status(status);
ac56fb13 2706
744cf19e 2707 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_REPLY, &rp,
4e51eae9 2708 sizeof(rp));
980e1a53 2709
a664b5bc 2710 mgmt_pending_remove(cmd);
980e1a53
JH
2711
2712 return err;
2713}
2714
744cf19e
JH
2715int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
2716 u8 status)
980e1a53
JH
2717{
2718 struct pending_cmd *cmd;
ac56fb13 2719 struct mgmt_rp_pin_code_reply rp;
980e1a53
JH
2720 int err;
2721
2e58ef3e 2722 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, hdev);
980e1a53
JH
2723 if (!cmd)
2724 return -ENOENT;
2725
ac56fb13 2726 bacpy(&rp.bdaddr, bdaddr);
ca69b795 2727 rp.status = mgmt_status(status);
ac56fb13 2728
744cf19e 2729 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY, &rp,
4e51eae9 2730 sizeof(rp));
980e1a53 2731
a664b5bc 2732 mgmt_pending_remove(cmd);
980e1a53
JH
2733
2734 return err;
2735}
a5c29683 2736
744cf19e
JH
2737int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
2738 __le32 value, u8 confirm_hint)
a5c29683
JH
2739{
2740 struct mgmt_ev_user_confirm_request ev;
2741
744cf19e 2742 BT_DBG("%s", hdev->name);
a5c29683 2743
a5c29683 2744 bacpy(&ev.bdaddr, bdaddr);
55bc1a37 2745 ev.confirm_hint = confirm_hint;
a5c29683
JH
2746 put_unaligned_le32(value, &ev.value);
2747
744cf19e 2748 return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, hdev, &ev, sizeof(ev),
4e51eae9 2749 NULL);
a5c29683
JH
2750}
2751
604086b7
BG
2752int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr)
2753{
2754 struct mgmt_ev_user_passkey_request ev;
2755
2756 BT_DBG("%s", hdev->name);
2757
2758 bacpy(&ev.bdaddr, bdaddr);
2759
2760 return mgmt_event(MGMT_EV_USER_PASSKEY_REQUEST, hdev, &ev, sizeof(ev),
2761 NULL);
2762}
2763
0df4c185 2764static int user_pairing_resp_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
744cf19e 2765 u8 status, u8 opcode)
a5c29683
JH
2766{
2767 struct pending_cmd *cmd;
2768 struct mgmt_rp_user_confirm_reply rp;
2769 int err;
2770
2e58ef3e 2771 cmd = mgmt_pending_find(opcode, hdev);
a5c29683
JH
2772 if (!cmd)
2773 return -ENOENT;
2774
a5c29683 2775 bacpy(&rp.bdaddr, bdaddr);
ca69b795 2776 rp.status = mgmt_status(status);
744cf19e 2777 err = cmd_complete(cmd->sk, hdev->id, opcode, &rp, sizeof(rp));
a5c29683 2778
a664b5bc 2779 mgmt_pending_remove(cmd);
a5c29683
JH
2780
2781 return err;
2782}
2783
744cf19e
JH
2784int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
2785 u8 status)
a5c29683 2786{
0df4c185 2787 return user_pairing_resp_complete(hdev, bdaddr, status,
a5c29683
JH
2788 MGMT_OP_USER_CONFIRM_REPLY);
2789}
2790
744cf19e
JH
2791int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev,
2792 bdaddr_t *bdaddr, u8 status)
a5c29683 2793{
0df4c185 2794 return user_pairing_resp_complete(hdev, bdaddr, status,
a5c29683
JH
2795 MGMT_OP_USER_CONFIRM_NEG_REPLY);
2796}
2a611692 2797
604086b7
BG
2798int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
2799 u8 status)
2800{
2801 return user_pairing_resp_complete(hdev, bdaddr, status,
2802 MGMT_OP_USER_PASSKEY_REPLY);
2803}
2804
2805int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev,
2806 bdaddr_t *bdaddr, u8 status)
2807{
2808 return user_pairing_resp_complete(hdev, bdaddr, status,
2809 MGMT_OP_USER_PASSKEY_NEG_REPLY);
2810}
2811
744cf19e 2812int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status)
2a611692
JH
2813{
2814 struct mgmt_ev_auth_failed ev;
2815
2a611692 2816 bacpy(&ev.bdaddr, bdaddr);
ca69b795 2817 ev.status = mgmt_status(status);
2a611692 2818
744cf19e 2819 return mgmt_event(MGMT_EV_AUTH_FAILED, hdev, &ev, sizeof(ev), NULL);
2a611692 2820}
b312b161 2821
744cf19e 2822int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status)
b312b161
JH
2823{
2824 struct pending_cmd *cmd;
2825 struct mgmt_cp_set_local_name ev;
2826 int err;
2827
2828 memset(&ev, 0, sizeof(ev));
2829 memcpy(ev.name, name, HCI_MAX_NAME_LENGTH);
2830
2e58ef3e 2831 cmd = mgmt_pending_find(MGMT_OP_SET_LOCAL_NAME, hdev);
b312b161
JH
2832 if (!cmd)
2833 goto send_event;
2834
2835 if (status) {
744cf19e 2836 err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
ca69b795 2837 mgmt_status(status));
b312b161
JH
2838 goto failed;
2839 }
2840
744cf19e 2841 update_eir(hdev);
80a1e1db 2842
744cf19e 2843 err = cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, &ev,
b312b161
JH
2844 sizeof(ev));
2845 if (err < 0)
2846 goto failed;
2847
2848send_event:
744cf19e 2849 err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev),
b312b161
JH
2850 cmd ? cmd->sk : NULL);
2851
2852failed:
2853 if (cmd)
2854 mgmt_pending_remove(cmd);
2855 return err;
2856}
c35938b2 2857
744cf19e
JH
2858int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
2859 u8 *randomizer, u8 status)
c35938b2
SJ
2860{
2861 struct pending_cmd *cmd;
2862 int err;
2863
744cf19e 2864 BT_DBG("%s status %u", hdev->name, status);
c35938b2 2865
2e58ef3e 2866 cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, hdev);
c35938b2
SJ
2867 if (!cmd)
2868 return -ENOENT;
2869
2870 if (status) {
744cf19e 2871 err = cmd_status(cmd->sk, hdev->id,
ca69b795
JH
2872 MGMT_OP_READ_LOCAL_OOB_DATA,
2873 mgmt_status(status));
c35938b2
SJ
2874 } else {
2875 struct mgmt_rp_read_local_oob_data rp;
2876
2877 memcpy(rp.hash, hash, sizeof(rp.hash));
2878 memcpy(rp.randomizer, randomizer, sizeof(rp.randomizer));
2879
744cf19e
JH
2880 err = cmd_complete(cmd->sk, hdev->id,
2881 MGMT_OP_READ_LOCAL_OOB_DATA,
2882 &rp, sizeof(rp));
c35938b2
SJ
2883 }
2884
2885 mgmt_pending_remove(cmd);
2886
2887 return err;
2888}
e17acd40 2889
48264f06 2890int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
561aafbc 2891 u8 addr_type, u8 *dev_class, s8 rssi,
e319d2e7 2892 u8 cfm_name, u8 *eir, u16 eir_len)
e17acd40 2893{
e319d2e7
JH
2894 char buf[512];
2895 struct mgmt_ev_device_found *ev = (void *) buf;
1dc06093 2896 size_t ev_size;
e17acd40 2897
1dc06093
JH
2898 /* Leave 5 bytes for a potential CoD field */
2899 if (sizeof(*ev) + eir_len + 5 > sizeof(buf))
7d262f86
AG
2900 return -EINVAL;
2901
1dc06093
JH
2902 memset(buf, 0, sizeof(buf));
2903
e319d2e7
JH
2904 bacpy(&ev->addr.bdaddr, bdaddr);
2905 ev->addr.type = link_to_mgmt(link_type, addr_type);
2906 ev->rssi = rssi;
2907 ev->confirm_name = cfm_name;
e17acd40 2908
1dc06093 2909 if (eir_len > 0)
e319d2e7 2910 memcpy(ev->eir, eir, eir_len);
e17acd40 2911
1dc06093
JH
2912 if (dev_class && !eir_has_data_type(ev->eir, eir_len, EIR_CLASS_OF_DEV))
2913 eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV,
2914 dev_class, 3);
2915
2916 put_unaligned_le16(eir_len, &ev->eir_len);
2917
2918 ev_size = sizeof(*ev) + eir_len;
f8523598 2919
e319d2e7 2920 return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL);
e17acd40 2921}
a88a9652 2922
b644ba33
JH
2923int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
2924 u8 addr_type, s8 rssi, u8 *name, u8 name_len)
a88a9652 2925{
b644ba33
JH
2926 struct mgmt_ev_device_found *ev;
2927 char buf[sizeof(*ev) + HCI_MAX_NAME_LENGTH + 2];
2928 u16 eir_len;
a88a9652 2929
b644ba33 2930 ev = (struct mgmt_ev_device_found *) buf;
a88a9652 2931
b644ba33
JH
2932 memset(buf, 0, sizeof(buf));
2933
2934 bacpy(&ev->addr.bdaddr, bdaddr);
2935 ev->addr.type = link_to_mgmt(link_type, addr_type);
2936 ev->rssi = rssi;
2937
2938 eir_len = eir_append_data(ev->eir, 0, EIR_NAME_COMPLETE, name,
2939 name_len);
2940
2941 put_unaligned_le16(eir_len, &ev->eir_len);
a88a9652 2942
b644ba33 2943 return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, &ev, sizeof(ev), NULL);
a88a9652 2944}
314b2381 2945
7a135109 2946int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status)
164a6e78
JH
2947{
2948 struct pending_cmd *cmd;
2949 int err;
2950
2e58ef3e 2951 cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev);
164a6e78
JH
2952 if (!cmd)
2953 return -ENOENT;
2954
ca69b795 2955 err = cmd_status(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status));
164a6e78
JH
2956 mgmt_pending_remove(cmd);
2957
2958 return err;
2959}
2960
e6d465cb
AG
2961int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status)
2962{
2963 struct pending_cmd *cmd;
2964 int err;
2965
2966 cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev);
2967 if (!cmd)
2968 return -ENOENT;
2969
e75a8b0c 2970 err = cmd_status(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status));
164a6e78
JH
2971 mgmt_pending_remove(cmd);
2972
2973 return err;
2974}
2975
744cf19e 2976int mgmt_discovering(struct hci_dev *hdev, u8 discovering)
314b2381 2977{
164a6e78
JH
2978 struct pending_cmd *cmd;
2979
2980 if (discovering)
2e58ef3e 2981 cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev);
164a6e78 2982 else
2e58ef3e 2983 cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev);
164a6e78
JH
2984
2985 if (cmd != NULL) {
744cf19e 2986 cmd_complete(cmd->sk, hdev->id, cmd->opcode, NULL, 0);
164a6e78
JH
2987 mgmt_pending_remove(cmd);
2988 }
2989
744cf19e 2990 return mgmt_event(MGMT_EV_DISCOVERING, hdev, &discovering,
314b2381
JH
2991 sizeof(discovering), NULL);
2992}
5e762444 2993
744cf19e 2994int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr)
5e762444
AJ
2995{
2996 struct pending_cmd *cmd;
2997 struct mgmt_ev_device_blocked ev;
2998
2e58ef3e 2999 cmd = mgmt_pending_find(MGMT_OP_BLOCK_DEVICE, hdev);
5e762444
AJ
3000
3001 bacpy(&ev.bdaddr, bdaddr);
3002
744cf19e
JH
3003 return mgmt_event(MGMT_EV_DEVICE_BLOCKED, hdev, &ev, sizeof(ev),
3004 cmd ? cmd->sk : NULL);
5e762444
AJ
3005}
3006
744cf19e 3007int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr)
5e762444
AJ
3008{
3009 struct pending_cmd *cmd;
3010 struct mgmt_ev_device_unblocked ev;
3011
2e58ef3e 3012 cmd = mgmt_pending_find(MGMT_OP_UNBLOCK_DEVICE, hdev);
5e762444
AJ
3013
3014 bacpy(&ev.bdaddr, bdaddr);
3015
744cf19e
JH
3016 return mgmt_event(MGMT_EV_DEVICE_UNBLOCKED, hdev, &ev, sizeof(ev),
3017 cmd ? cmd->sk : NULL);
5e762444 3018}
This page took 0.313365 seconds and 5 git commands to generate.