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