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