aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r--net/bluetooth/mgmt.c1250
1 files changed, 1167 insertions, 83 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index f827fd908380..f5ef7a3374c7 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -22,7 +22,7 @@
22 22
23/* Bluetooth HCI Management interface */ 23/* Bluetooth HCI Management interface */
24 24
25#include <asm/uaccess.h> 25#include <linux/uaccess.h>
26#include <asm/unaligned.h> 26#include <asm/unaligned.h>
27 27
28#include <net/bluetooth/bluetooth.h> 28#include <net/bluetooth/bluetooth.h>
@@ -32,6 +32,16 @@
32#define MGMT_VERSION 0 32#define MGMT_VERSION 0
33#define MGMT_REVISION 1 33#define MGMT_REVISION 1
34 34
35struct pending_cmd {
36 struct list_head list;
37 __u16 opcode;
38 int index;
39 void *cmd;
40 struct sock *sk;
41};
42
43LIST_HEAD(cmd_list);
44
35static int cmd_status(struct sock *sk, u16 cmd, u8 status) 45static int cmd_status(struct sock *sk, u16 cmd, u8 status)
36{ 46{
37 struct sk_buff *skb; 47 struct sk_buff *skb;
@@ -59,29 +69,26 @@ static int cmd_status(struct sock *sk, u16 cmd, u8 status)
59 return 0; 69 return 0;
60} 70}
61 71
62static int read_version(struct sock *sk) 72static int cmd_complete(struct sock *sk, u16 cmd, void *rp, size_t rp_len)
63{ 73{
64 struct sk_buff *skb; 74 struct sk_buff *skb;
65 struct mgmt_hdr *hdr; 75 struct mgmt_hdr *hdr;
66 struct mgmt_ev_cmd_complete *ev; 76 struct mgmt_ev_cmd_complete *ev;
67 struct mgmt_rp_read_version *rp;
68 77
69 BT_DBG("sock %p", sk); 78 BT_DBG("sock %p", sk);
70 79
71 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC); 80 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_ATOMIC);
72 if (!skb) 81 if (!skb)
73 return -ENOMEM; 82 return -ENOMEM;
74 83
75 hdr = (void *) skb_put(skb, sizeof(*hdr)); 84 hdr = (void *) skb_put(skb, sizeof(*hdr));
76 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
77 hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp));
78 85
79 ev = (void *) skb_put(skb, sizeof(*ev)); 86 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
80 put_unaligned_le16(MGMT_OP_READ_VERSION, &ev->opcode); 87 hdr->len = cpu_to_le16(sizeof(*ev) + rp_len);
81 88
82 rp = (void *) skb_put(skb, sizeof(*rp)); 89 ev = (void *) skb_put(skb, sizeof(*ev) + rp_len);
83 rp->version = MGMT_VERSION; 90 put_unaligned_le16(cmd, &ev->opcode);
84 put_unaligned_le16(MGMT_REVISION, &rp->revision); 91 memcpy(ev->data, rp, rp_len);
85 92
86 if (sock_queue_rcv_skb(sk, skb) < 0) 93 if (sock_queue_rcv_skb(sk, skb) < 0)
87 kfree_skb(skb); 94 kfree_skb(skb);
@@ -89,16 +96,25 @@ static int read_version(struct sock *sk)
89 return 0; 96 return 0;
90} 97}
91 98
99static int read_version(struct sock *sk)
100{
101 struct mgmt_rp_read_version rp;
102
103 BT_DBG("sock %p", sk);
104
105 rp.version = MGMT_VERSION;
106 put_unaligned_le16(MGMT_REVISION, &rp.revision);
107
108 return cmd_complete(sk, MGMT_OP_READ_VERSION, &rp, sizeof(rp));
109}
110
92static int read_index_list(struct sock *sk) 111static int read_index_list(struct sock *sk)
93{ 112{
94 struct sk_buff *skb;
95 struct mgmt_hdr *hdr;
96 struct mgmt_ev_cmd_complete *ev;
97 struct mgmt_rp_read_index_list *rp; 113 struct mgmt_rp_read_index_list *rp;
98 struct list_head *p; 114 struct list_head *p;
99 size_t body_len; 115 size_t rp_len;
100 u16 count; 116 u16 count;
101 int i; 117 int i, err;
102 118
103 BT_DBG("sock %p", sk); 119 BT_DBG("sock %p", sk);
104 120
@@ -109,43 +125,43 @@ static int read_index_list(struct sock *sk)
109 count++; 125 count++;
110 } 126 }
111 127
112 body_len = sizeof(*ev) + sizeof(*rp) + (2 * count); 128 rp_len = sizeof(*rp) + (2 * count);
113 skb = alloc_skb(sizeof(*hdr) + body_len, GFP_ATOMIC); 129 rp = kmalloc(rp_len, GFP_ATOMIC);
114 if (!skb) 130 if (!rp) {
131 read_unlock(&hci_dev_list_lock);
115 return -ENOMEM; 132 return -ENOMEM;
133 }
116 134
117 hdr = (void *) skb_put(skb, sizeof(*hdr));
118 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
119 hdr->len = cpu_to_le16(body_len);
120
121 ev = (void *) skb_put(skb, sizeof(*ev));
122 put_unaligned_le16(MGMT_OP_READ_INDEX_LIST, &ev->opcode);
123
124 rp = (void *) skb_put(skb, sizeof(*rp) + (2 * count));
125 put_unaligned_le16(count, &rp->num_controllers); 135 put_unaligned_le16(count, &rp->num_controllers);
126 136
127 i = 0; 137 i = 0;
128 list_for_each(p, &hci_dev_list) { 138 list_for_each(p, &hci_dev_list) {
129 struct hci_dev *d = list_entry(p, struct hci_dev, list); 139 struct hci_dev *d = list_entry(p, struct hci_dev, list);
140
141 hci_del_off_timer(d);
142
143 set_bit(HCI_MGMT, &d->flags);
144
145 if (test_bit(HCI_SETUP, &d->flags))
146 continue;
147
130 put_unaligned_le16(d->id, &rp->index[i++]); 148 put_unaligned_le16(d->id, &rp->index[i++]);
131 BT_DBG("Added hci%u", d->id); 149 BT_DBG("Added hci%u", d->id);
132 } 150 }
133 151
134 read_unlock(&hci_dev_list_lock); 152 read_unlock(&hci_dev_list_lock);
135 153
136 if (sock_queue_rcv_skb(sk, skb) < 0) 154 err = cmd_complete(sk, MGMT_OP_READ_INDEX_LIST, rp, rp_len);
137 kfree_skb(skb);
138 155
139 return 0; 156 kfree(rp);
157
158 return err;
140} 159}
141 160
142static int read_controller_info(struct sock *sk, unsigned char *data, u16 len) 161static int read_controller_info(struct sock *sk, unsigned char *data, u16 len)
143{ 162{
144 struct sk_buff *skb; 163 struct mgmt_rp_read_info rp;
145 struct mgmt_hdr *hdr; 164 struct mgmt_cp_read_info *cp = (void *) data;
146 struct mgmt_ev_cmd_complete *ev;
147 struct mgmt_rp_read_info *rp;
148 struct mgmt_cp_read_info *cp;
149 struct hci_dev *hdev; 165 struct hci_dev *hdev;
150 u16 dev_id; 166 u16 dev_id;
151 167
@@ -154,18 +170,333 @@ static int read_controller_info(struct sock *sk, unsigned char *data, u16 len)
154 if (len != 2) 170 if (len != 2)
155 return cmd_status(sk, MGMT_OP_READ_INFO, EINVAL); 171 return cmd_status(sk, MGMT_OP_READ_INFO, EINVAL);
156 172
157 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC); 173 dev_id = get_unaligned_le16(&cp->index);
174
175 BT_DBG("request for hci%u", dev_id);
176
177 hdev = hci_dev_get(dev_id);
178 if (!hdev)
179 return cmd_status(sk, MGMT_OP_READ_INFO, ENODEV);
180
181 hci_del_off_timer(hdev);
182
183 hci_dev_lock_bh(hdev);
184
185 set_bit(HCI_MGMT, &hdev->flags);
186
187 put_unaligned_le16(hdev->id, &rp.index);
188 rp.type = hdev->dev_type;
189
190 rp.powered = test_bit(HCI_UP, &hdev->flags);
191 rp.connectable = test_bit(HCI_PSCAN, &hdev->flags);
192 rp.discoverable = test_bit(HCI_ISCAN, &hdev->flags);
193 rp.pairable = test_bit(HCI_PSCAN, &hdev->flags);
194
195 if (test_bit(HCI_AUTH, &hdev->flags))
196 rp.sec_mode = 3;
197 else if (hdev->ssp_mode > 0)
198 rp.sec_mode = 4;
199 else
200 rp.sec_mode = 2;
201
202 bacpy(&rp.bdaddr, &hdev->bdaddr);
203 memcpy(rp.features, hdev->features, 8);
204 memcpy(rp.dev_class, hdev->dev_class, 3);
205 put_unaligned_le16(hdev->manufacturer, &rp.manufacturer);
206 rp.hci_ver = hdev->hci_ver;
207 put_unaligned_le16(hdev->hci_rev, &rp.hci_rev);
208
209 hci_dev_unlock_bh(hdev);
210 hci_dev_put(hdev);
211
212 return cmd_complete(sk, MGMT_OP_READ_INFO, &rp, sizeof(rp));
213}
214
215static void mgmt_pending_free(struct pending_cmd *cmd)
216{
217 sock_put(cmd->sk);
218 kfree(cmd->cmd);
219 kfree(cmd);
220}
221
222static int mgmt_pending_add(struct sock *sk, u16 opcode, int index,
223 void *data, u16 len)
224{
225 struct pending_cmd *cmd;
226
227 cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
228 if (!cmd)
229 return -ENOMEM;
230
231 cmd->opcode = opcode;
232 cmd->index = index;
233
234 cmd->cmd = kmalloc(len, GFP_ATOMIC);
235 if (!cmd->cmd) {
236 kfree(cmd);
237 return -ENOMEM;
238 }
239
240 memcpy(cmd->cmd, data, len);
241
242 cmd->sk = sk;
243 sock_hold(sk);
244
245 list_add(&cmd->list, &cmd_list);
246
247 return 0;
248}
249
250static void mgmt_pending_foreach(u16 opcode, int index,
251 void (*cb)(struct pending_cmd *cmd, void *data),
252 void *data)
253{
254 struct list_head *p, *n;
255
256 list_for_each_safe(p, n, &cmd_list) {
257 struct pending_cmd *cmd;
258
259 cmd = list_entry(p, struct pending_cmd, list);
260
261 if (cmd->opcode != opcode)
262 continue;
263
264 if (index >= 0 && cmd->index != index)
265 continue;
266
267 cb(cmd, data);
268 }
269}
270
271static struct pending_cmd *mgmt_pending_find(u16 opcode, int index)
272{
273 struct list_head *p;
274
275 list_for_each(p, &cmd_list) {
276 struct pending_cmd *cmd;
277
278 cmd = list_entry(p, struct pending_cmd, list);
279
280 if (cmd->opcode != opcode)
281 continue;
282
283 if (index >= 0 && cmd->index != index)
284 continue;
285
286 return cmd;
287 }
288
289 return NULL;
290}
291
292static void mgmt_pending_remove(u16 opcode, int index)
293{
294 struct pending_cmd *cmd;
295
296 cmd = mgmt_pending_find(opcode, index);
297 if (cmd == NULL)
298 return;
299
300 list_del(&cmd->list);
301 mgmt_pending_free(cmd);
302}
303
304static int set_powered(struct sock *sk, unsigned char *data, u16 len)
305{
306 struct mgmt_mode *cp;
307 struct hci_dev *hdev;
308 u16 dev_id;
309 int ret, up;
310
311 cp = (void *) data;
312 dev_id = get_unaligned_le16(&cp->index);
313
314 BT_DBG("request for hci%u", dev_id);
315
316 hdev = hci_dev_get(dev_id);
317 if (!hdev)
318 return cmd_status(sk, MGMT_OP_SET_POWERED, ENODEV);
319
320 hci_dev_lock_bh(hdev);
321
322 up = test_bit(HCI_UP, &hdev->flags);
323 if ((cp->val && up) || (!cp->val && !up)) {
324 ret = cmd_status(sk, MGMT_OP_SET_POWERED, EALREADY);
325 goto failed;
326 }
327
328 if (mgmt_pending_find(MGMT_OP_SET_POWERED, dev_id)) {
329 ret = cmd_status(sk, MGMT_OP_SET_POWERED, EBUSY);
330 goto failed;
331 }
332
333 ret = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, dev_id, data, len);
334 if (ret < 0)
335 goto failed;
336
337 if (cp->val)
338 queue_work(hdev->workqueue, &hdev->power_on);
339 else
340 queue_work(hdev->workqueue, &hdev->power_off);
341
342 ret = 0;
343
344failed:
345 hci_dev_unlock_bh(hdev);
346 hci_dev_put(hdev);
347 return ret;
348}
349
350static int set_discoverable(struct sock *sk, unsigned char *data, u16 len)
351{
352 struct mgmt_mode *cp;
353 struct hci_dev *hdev;
354 u16 dev_id;
355 u8 scan;
356 int err;
357
358 cp = (void *) data;
359 dev_id = get_unaligned_le16(&cp->index);
360
361 BT_DBG("request for hci%u", dev_id);
362
363 hdev = hci_dev_get(dev_id);
364 if (!hdev)
365 return cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, ENODEV);
366
367 hci_dev_lock_bh(hdev);
368
369 if (!test_bit(HCI_UP, &hdev->flags)) {
370 err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, ENETDOWN);
371 goto failed;
372 }
373
374 if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, dev_id) ||
375 mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, dev_id)) {
376 err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, EBUSY);
377 goto failed;
378 }
379
380 if (cp->val == test_bit(HCI_ISCAN, &hdev->flags) &&
381 test_bit(HCI_PSCAN, &hdev->flags)) {
382 err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, EALREADY);
383 goto failed;
384 }
385
386 err = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, dev_id, data, len);
387 if (err < 0)
388 goto failed;
389
390 scan = SCAN_PAGE;
391
392 if (cp->val)
393 scan |= SCAN_INQUIRY;
394
395 err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
396 if (err < 0)
397 mgmt_pending_remove(MGMT_OP_SET_DISCOVERABLE, dev_id);
398
399failed:
400 hci_dev_unlock_bh(hdev);
401 hci_dev_put(hdev);
402
403 return err;
404}
405
406static int set_connectable(struct sock *sk, unsigned char *data, u16 len)
407{
408 struct mgmt_mode *cp;
409 struct hci_dev *hdev;
410 u16 dev_id;
411 u8 scan;
412 int err;
413
414 cp = (void *) data;
415 dev_id = get_unaligned_le16(&cp->index);
416
417 BT_DBG("request for hci%u", dev_id);
418
419 hdev = hci_dev_get(dev_id);
420 if (!hdev)
421 return cmd_status(sk, MGMT_OP_SET_CONNECTABLE, ENODEV);
422
423 hci_dev_lock_bh(hdev);
424
425 if (!test_bit(HCI_UP, &hdev->flags)) {
426 err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, ENETDOWN);
427 goto failed;
428 }
429
430 if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, dev_id) ||
431 mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, dev_id)) {
432 err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, EBUSY);
433 goto failed;
434 }
435
436 if (cp->val == test_bit(HCI_PSCAN, &hdev->flags)) {
437 err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, EALREADY);
438 goto failed;
439 }
440
441 err = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, dev_id, data, len);
442 if (err < 0)
443 goto failed;
444
445 if (cp->val)
446 scan = SCAN_PAGE;
447 else
448 scan = 0;
449
450 err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
451 if (err < 0)
452 mgmt_pending_remove(MGMT_OP_SET_CONNECTABLE, dev_id);
453
454failed:
455 hci_dev_unlock_bh(hdev);
456 hci_dev_put(hdev);
457
458 return err;
459}
460
461static int mgmt_event(u16 event, void *data, u16 data_len, struct sock *skip_sk)
462{
463 struct sk_buff *skb;
464 struct mgmt_hdr *hdr;
465
466 skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC);
158 if (!skb) 467 if (!skb)
159 return -ENOMEM; 468 return -ENOMEM;
160 469
470 bt_cb(skb)->channel = HCI_CHANNEL_CONTROL;
471
161 hdr = (void *) skb_put(skb, sizeof(*hdr)); 472 hdr = (void *) skb_put(skb, sizeof(*hdr));
162 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); 473 hdr->opcode = cpu_to_le16(event);
163 hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp)); 474 hdr->len = cpu_to_le16(data_len);
164 475
165 ev = (void *) skb_put(skb, sizeof(*ev)); 476 memcpy(skb_put(skb, data_len), data, data_len);
166 put_unaligned_le16(MGMT_OP_READ_INFO, &ev->opcode);
167 477
168 rp = (void *) skb_put(skb, sizeof(*rp)); 478 hci_send_to_sock(NULL, skb, skip_sk);
479 kfree_skb(skb);
480
481 return 0;
482}
483
484static int send_mode_rsp(struct sock *sk, u16 opcode, u16 index, u8 val)
485{
486 struct mgmt_mode rp;
487
488 put_unaligned_le16(index, &rp.index);
489 rp.val = val;
490
491 return cmd_complete(sk, opcode, &rp, sizeof(rp));
492}
493
494static int set_pairable(struct sock *sk, unsigned char *data, u16 len)
495{
496 struct mgmt_mode *cp, ev;
497 struct hci_dev *hdev;
498 u16 dev_id;
499 int err;
169 500
170 cp = (void *) data; 501 cp = (void *) data;
171 dev_id = get_unaligned_le16(&cp->index); 502 dev_id = get_unaligned_le16(&cp->index);
@@ -173,43 +504,547 @@ static int read_controller_info(struct sock *sk, unsigned char *data, u16 len)
173 BT_DBG("request for hci%u", dev_id); 504 BT_DBG("request for hci%u", dev_id);
174 505
175 hdev = hci_dev_get(dev_id); 506 hdev = hci_dev_get(dev_id);
176 if (!hdev) { 507 if (!hdev)
177 kfree_skb(skb); 508 return cmd_status(sk, MGMT_OP_SET_PAIRABLE, ENODEV);
178 return cmd_status(sk, MGMT_OP_READ_INFO, ENODEV); 509
510 hci_dev_lock_bh(hdev);
511
512 if (cp->val)
513 set_bit(HCI_PAIRABLE, &hdev->flags);
514 else
515 clear_bit(HCI_PAIRABLE, &hdev->flags);
516
517 err = send_mode_rsp(sk, MGMT_OP_SET_PAIRABLE, dev_id, cp->val);
518 if (err < 0)
519 goto failed;
520
521 put_unaligned_le16(dev_id, &ev.index);
522 ev.val = cp->val;
523
524 err = mgmt_event(MGMT_EV_PAIRABLE, &ev, sizeof(ev), sk);
525
526failed:
527 hci_dev_unlock_bh(hdev);
528 hci_dev_put(hdev);
529
530 return err;
531}
532
533static u8 get_service_classes(struct hci_dev *hdev)
534{
535 struct list_head *p;
536 u8 val = 0;
537
538 list_for_each(p, &hdev->uuids) {
539 struct bt_uuid *uuid = list_entry(p, struct bt_uuid, list);
540
541 val |= uuid->svc_hint;
542 }
543
544 return val;
545}
546
547static int update_class(struct hci_dev *hdev)
548{
549 u8 cod[3];
550
551 BT_DBG("%s", hdev->name);
552
553 if (test_bit(HCI_SERVICE_CACHE, &hdev->flags))
554 return 0;
555
556 cod[0] = hdev->minor_class;
557 cod[1] = hdev->major_class;
558 cod[2] = get_service_classes(hdev);
559
560 if (memcmp(cod, hdev->dev_class, 3) == 0)
561 return 0;
562
563 return hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
564}
565
566static int add_uuid(struct sock *sk, unsigned char *data, u16 len)
567{
568 struct mgmt_cp_add_uuid *cp;
569 struct hci_dev *hdev;
570 struct bt_uuid *uuid;
571 u16 dev_id;
572 int err;
573
574 cp = (void *) data;
575 dev_id = get_unaligned_le16(&cp->index);
576
577 BT_DBG("request for hci%u", dev_id);
578
579 hdev = hci_dev_get(dev_id);
580 if (!hdev)
581 return cmd_status(sk, MGMT_OP_ADD_UUID, ENODEV);
582
583 hci_dev_lock_bh(hdev);
584
585 uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC);
586 if (!uuid) {
587 err = -ENOMEM;
588 goto failed;
179 } 589 }
180 590
591 memcpy(uuid->uuid, cp->uuid, 16);
592 uuid->svc_hint = cp->svc_hint;
593
594 list_add(&uuid->list, &hdev->uuids);
595
596 err = update_class(hdev);
597 if (err < 0)
598 goto failed;
599
600 err = cmd_complete(sk, MGMT_OP_ADD_UUID, &dev_id, sizeof(dev_id));
601
602failed:
603 hci_dev_unlock_bh(hdev);
604 hci_dev_put(hdev);
605
606 return err;
607}
608
609static int remove_uuid(struct sock *sk, unsigned char *data, u16 len)
610{
611 struct list_head *p, *n;
612 struct mgmt_cp_add_uuid *cp;
613 struct hci_dev *hdev;
614 u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
615 u16 dev_id;
616 int err, found;
617
618 cp = (void *) data;
619 dev_id = get_unaligned_le16(&cp->index);
620
621 BT_DBG("request for hci%u", dev_id);
622
623 hdev = hci_dev_get(dev_id);
624 if (!hdev)
625 return cmd_status(sk, MGMT_OP_REMOVE_UUID, ENODEV);
626
181 hci_dev_lock_bh(hdev); 627 hci_dev_lock_bh(hdev);
182 628
183 put_unaligned_le16(hdev->id, &rp->index); 629 if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) {
184 rp->type = hdev->dev_type; 630 err = hci_uuids_clear(hdev);
631 goto unlock;
632 }
185 633
186 rp->powered = test_bit(HCI_UP, &hdev->flags); 634 found = 0;
187 rp->discoverable = test_bit(HCI_ISCAN, &hdev->flags);
188 rp->pairable = test_bit(HCI_PSCAN, &hdev->flags);
189 635
190 if (test_bit(HCI_AUTH, &hdev->flags)) 636 list_for_each_safe(p, n, &hdev->uuids) {
191 rp->sec_mode = 3; 637 struct bt_uuid *match = list_entry(p, struct bt_uuid, list);
192 else if (hdev->ssp_mode > 0)
193 rp->sec_mode = 4;
194 else
195 rp->sec_mode = 2;
196 638
197 bacpy(&rp->bdaddr, &hdev->bdaddr); 639 if (memcmp(match->uuid, cp->uuid, 16) != 0)
198 memcpy(rp->features, hdev->features, 8); 640 continue;
199 memcpy(rp->dev_class, hdev->dev_class, 3);
200 put_unaligned_le16(hdev->manufacturer, &rp->manufacturer);
201 rp->hci_ver = hdev->hci_ver;
202 put_unaligned_le16(hdev->hci_rev, &rp->hci_rev);
203 641
642 list_del(&match->list);
643 found++;
644 }
645
646 if (found == 0) {
647 err = cmd_status(sk, MGMT_OP_REMOVE_UUID, ENOENT);
648 goto unlock;
649 }
650
651 err = update_class(hdev);
652 if (err < 0)
653 goto unlock;
654
655 err = cmd_complete(sk, MGMT_OP_REMOVE_UUID, &dev_id, sizeof(dev_id));
656
657unlock:
204 hci_dev_unlock_bh(hdev); 658 hci_dev_unlock_bh(hdev);
205 hci_dev_put(hdev); 659 hci_dev_put(hdev);
206 660
207 if (sock_queue_rcv_skb(sk, skb) < 0) 661 return err;
208 kfree_skb(skb); 662}
663
664static int set_dev_class(struct sock *sk, unsigned char *data, u16 len)
665{
666 struct hci_dev *hdev;
667 struct mgmt_cp_set_dev_class *cp;
668 u16 dev_id;
669 int err;
670
671 cp = (void *) data;
672 dev_id = get_unaligned_le16(&cp->index);
673
674 BT_DBG("request for hci%u", dev_id);
675
676 hdev = hci_dev_get(dev_id);
677 if (!hdev)
678 return cmd_status(sk, MGMT_OP_SET_DEV_CLASS, ENODEV);
679
680 hci_dev_lock_bh(hdev);
681
682 hdev->major_class = cp->major;
683 hdev->minor_class = cp->minor;
684
685 err = update_class(hdev);
686
687 if (err == 0)
688 err = cmd_complete(sk, MGMT_OP_SET_DEV_CLASS, &dev_id,
689 sizeof(dev_id));
690
691 hci_dev_unlock_bh(hdev);
692 hci_dev_put(hdev);
693
694 return err;
695}
696
697static int set_service_cache(struct sock *sk, unsigned char *data, u16 len)
698{
699 struct hci_dev *hdev;
700 struct mgmt_cp_set_service_cache *cp;
701 u16 dev_id;
702 int err;
703
704 cp = (void *) data;
705 dev_id = get_unaligned_le16(&cp->index);
706
707 hdev = hci_dev_get(dev_id);
708 if (!hdev)
709 return cmd_status(sk, MGMT_OP_SET_SERVICE_CACHE, ENODEV);
710
711 hci_dev_lock_bh(hdev);
712
713 BT_DBG("hci%u enable %d", dev_id, cp->enable);
714
715 if (cp->enable) {
716 set_bit(HCI_SERVICE_CACHE, &hdev->flags);
717 err = 0;
718 } else {
719 clear_bit(HCI_SERVICE_CACHE, &hdev->flags);
720 err = update_class(hdev);
721 }
722
723 if (err == 0)
724 err = cmd_complete(sk, MGMT_OP_SET_SERVICE_CACHE, &dev_id,
725 sizeof(dev_id));
726
727 hci_dev_unlock_bh(hdev);
728 hci_dev_put(hdev);
729
730 return err;
731}
732
733static int load_keys(struct sock *sk, unsigned char *data, u16 len)
734{
735 struct hci_dev *hdev;
736 struct mgmt_cp_load_keys *cp;
737 u16 dev_id, key_count, expected_len;
738 int i;
739
740 cp = (void *) data;
741 dev_id = get_unaligned_le16(&cp->index);
742 key_count = get_unaligned_le16(&cp->key_count);
743
744 expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info);
745 if (expected_len != len) {
746 BT_ERR("load_keys: expected %u bytes, got %u bytes",
747 len, expected_len);
748 return -EINVAL;
749 }
750
751 hdev = hci_dev_get(dev_id);
752 if (!hdev)
753 return cmd_status(sk, MGMT_OP_LOAD_KEYS, ENODEV);
754
755 BT_DBG("hci%u debug_keys %u key_count %u", dev_id, cp->debug_keys,
756 key_count);
757
758 hci_dev_lock_bh(hdev);
759
760 hci_link_keys_clear(hdev);
761
762 set_bit(HCI_LINK_KEYS, &hdev->flags);
763
764 if (cp->debug_keys)
765 set_bit(HCI_DEBUG_KEYS, &hdev->flags);
766 else
767 clear_bit(HCI_DEBUG_KEYS, &hdev->flags);
768
769 for (i = 0; i < key_count; i++) {
770 struct mgmt_key_info *key = &cp->keys[i];
771
772 hci_add_link_key(hdev, 0, &key->bdaddr, key->val, key->type,
773 key->pin_len);
774 }
775
776 hci_dev_unlock_bh(hdev);
777 hci_dev_put(hdev);
209 778
210 return 0; 779 return 0;
211} 780}
212 781
782static int remove_key(struct sock *sk, unsigned char *data, u16 len)
783{
784 struct hci_dev *hdev;
785 struct mgmt_cp_remove_key *cp;
786 struct hci_conn *conn;
787 u16 dev_id;
788 int err;
789
790 cp = (void *) data;
791 dev_id = get_unaligned_le16(&cp->index);
792
793 hdev = hci_dev_get(dev_id);
794 if (!hdev)
795 return cmd_status(sk, MGMT_OP_REMOVE_KEY, ENODEV);
796
797 hci_dev_lock_bh(hdev);
798
799 err = hci_remove_link_key(hdev, &cp->bdaddr);
800 if (err < 0) {
801 err = cmd_status(sk, MGMT_OP_REMOVE_KEY, -err);
802 goto unlock;
803 }
804
805 err = 0;
806
807 if (!test_bit(HCI_UP, &hdev->flags) || !cp->disconnect)
808 goto unlock;
809
810 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
811 if (conn) {
812 struct hci_cp_disconnect dc;
813
814 put_unaligned_le16(conn->handle, &dc.handle);
815 dc.reason = 0x13; /* Remote User Terminated Connection */
816 err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, 0, NULL);
817 }
818
819unlock:
820 hci_dev_unlock_bh(hdev);
821 hci_dev_put(hdev);
822
823 return err;
824}
825
826static int disconnect(struct sock *sk, unsigned char *data, u16 len)
827{
828 struct hci_dev *hdev;
829 struct mgmt_cp_disconnect *cp;
830 struct hci_cp_disconnect dc;
831 struct hci_conn *conn;
832 u16 dev_id;
833 int err;
834
835 BT_DBG("");
836
837 cp = (void *) data;
838 dev_id = get_unaligned_le16(&cp->index);
839
840 hdev = hci_dev_get(dev_id);
841 if (!hdev)
842 return cmd_status(sk, MGMT_OP_DISCONNECT, ENODEV);
843
844 hci_dev_lock_bh(hdev);
845
846 if (!test_bit(HCI_UP, &hdev->flags)) {
847 err = cmd_status(sk, MGMT_OP_DISCONNECT, ENETDOWN);
848 goto failed;
849 }
850
851 if (mgmt_pending_find(MGMT_OP_DISCONNECT, dev_id)) {
852 err = cmd_status(sk, MGMT_OP_DISCONNECT, EBUSY);
853 goto failed;
854 }
855
856 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
857 if (!conn) {
858 err = cmd_status(sk, MGMT_OP_DISCONNECT, ENOTCONN);
859 goto failed;
860 }
861
862 err = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, dev_id, data, len);
863 if (err < 0)
864 goto failed;
865
866 put_unaligned_le16(conn->handle, &dc.handle);
867 dc.reason = 0x13; /* Remote User Terminated Connection */
868
869 err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc);
870 if (err < 0)
871 mgmt_pending_remove(MGMT_OP_DISCONNECT, dev_id);
872
873failed:
874 hci_dev_unlock_bh(hdev);
875 hci_dev_put(hdev);
876
877 return err;
878}
879
880static int get_connections(struct sock *sk, unsigned char *data, u16 len)
881{
882 struct mgmt_cp_get_connections *cp;
883 struct mgmt_rp_get_connections *rp;
884 struct hci_dev *hdev;
885 struct list_head *p;
886 size_t rp_len;
887 u16 dev_id, count;
888 int i, err;
889
890 BT_DBG("");
891
892 cp = (void *) data;
893 dev_id = get_unaligned_le16(&cp->index);
894
895 hdev = hci_dev_get(dev_id);
896 if (!hdev)
897 return cmd_status(sk, MGMT_OP_GET_CONNECTIONS, ENODEV);
898
899 hci_dev_lock_bh(hdev);
900
901 count = 0;
902 list_for_each(p, &hdev->conn_hash.list) {
903 count++;
904 }
905
906 rp_len = sizeof(*rp) + (count * sizeof(bdaddr_t));
907 rp = kmalloc(rp_len, GFP_ATOMIC);
908 if (!rp) {
909 err = -ENOMEM;
910 goto unlock;
911 }
912
913 put_unaligned_le16(dev_id, &rp->index);
914 put_unaligned_le16(count, &rp->conn_count);
915
916 read_lock(&hci_dev_list_lock);
917
918 i = 0;
919 list_for_each(p, &hdev->conn_hash.list) {
920 struct hci_conn *c = list_entry(p, struct hci_conn, list);
921
922 bacpy(&rp->conn[i++], &c->dst);
923 }
924
925 read_unlock(&hci_dev_list_lock);
926
927 err = cmd_complete(sk, MGMT_OP_GET_CONNECTIONS, rp, rp_len);
928
929unlock:
930 kfree(rp);
931 hci_dev_unlock_bh(hdev);
932 hci_dev_put(hdev);
933 return err;
934}
935
936static int pin_code_reply(struct sock *sk, unsigned char *data, u16 len)
937{
938 struct hci_dev *hdev;
939 struct mgmt_cp_pin_code_reply *cp;
940 struct hci_cp_pin_code_reply reply;
941 u16 dev_id;
942 int err;
943
944 BT_DBG("");
945
946 cp = (void *) data;
947 dev_id = get_unaligned_le16(&cp->index);
948
949 hdev = hci_dev_get(dev_id);
950 if (!hdev)
951 return cmd_status(sk, MGMT_OP_DISCONNECT, ENODEV);
952
953 hci_dev_lock_bh(hdev);
954
955 if (!test_bit(HCI_UP, &hdev->flags)) {
956 err = cmd_status(sk, MGMT_OP_PIN_CODE_REPLY, ENETDOWN);
957 goto failed;
958 }
959
960 err = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, dev_id, data, len);
961 if (err < 0)
962 goto failed;
963
964 bacpy(&reply.bdaddr, &cp->bdaddr);
965 reply.pin_len = cp->pin_len;
966 memcpy(reply.pin_code, cp->pin_code, 16);
967
968 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_REPLY, sizeof(reply), &reply);
969 if (err < 0)
970 mgmt_pending_remove(MGMT_OP_PIN_CODE_REPLY, dev_id);
971
972failed:
973 hci_dev_unlock_bh(hdev);
974 hci_dev_put(hdev);
975
976 return err;
977}
978
979static int pin_code_neg_reply(struct sock *sk, unsigned char *data, u16 len)
980{
981 struct hci_dev *hdev;
982 struct mgmt_cp_pin_code_neg_reply *cp;
983 u16 dev_id;
984 int err;
985
986 BT_DBG("");
987
988 cp = (void *) data;
989 dev_id = get_unaligned_le16(&cp->index);
990
991 hdev = hci_dev_get(dev_id);
992 if (!hdev)
993 return cmd_status(sk, MGMT_OP_PIN_CODE_NEG_REPLY, ENODEV);
994
995 hci_dev_lock_bh(hdev);
996
997 if (!test_bit(HCI_UP, &hdev->flags)) {
998 err = cmd_status(sk, MGMT_OP_PIN_CODE_NEG_REPLY, ENETDOWN);
999 goto failed;
1000 }
1001
1002 err = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, dev_id,
1003 data, len);
1004 if (err < 0)
1005 goto failed;
1006
1007 err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(bdaddr_t),
1008 &cp->bdaddr);
1009 if (err < 0)
1010 mgmt_pending_remove(MGMT_OP_PIN_CODE_NEG_REPLY, dev_id);
1011
1012failed:
1013 hci_dev_unlock_bh(hdev);
1014 hci_dev_put(hdev);
1015
1016 return err;
1017}
1018
1019static int set_io_capability(struct sock *sk, unsigned char *data, u16 len)
1020{
1021 struct hci_dev *hdev;
1022 struct mgmt_cp_set_io_capability *cp;
1023 u16 dev_id;
1024
1025 BT_DBG("");
1026
1027 cp = (void *) data;
1028 dev_id = get_unaligned_le16(&cp->index);
1029
1030 hdev = hci_dev_get(dev_id);
1031 if (!hdev)
1032 return cmd_status(sk, MGMT_OP_SET_IO_CAPABILITY, ENODEV);
1033
1034 hci_dev_lock_bh(hdev);
1035
1036 hdev->io_capability = cp->io_capability;
1037
1038 BT_DBG("%s IO capability set to 0x%02x", hdev->name,
1039 hdev->io_capability);
1040
1041 hci_dev_unlock_bh(hdev);
1042 hci_dev_put(hdev);
1043
1044 return cmd_complete(sk, MGMT_OP_SET_IO_CAPABILITY,
1045 &dev_id, sizeof(dev_id));
1046}
1047
213int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) 1048int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
214{ 1049{
215 unsigned char *buf; 1050 unsigned char *buf;
@@ -250,6 +1085,51 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
250 case MGMT_OP_READ_INFO: 1085 case MGMT_OP_READ_INFO:
251 err = read_controller_info(sk, buf + sizeof(*hdr), len); 1086 err = read_controller_info(sk, buf + sizeof(*hdr), len);
252 break; 1087 break;
1088 case MGMT_OP_SET_POWERED:
1089 err = set_powered(sk, buf + sizeof(*hdr), len);
1090 break;
1091 case MGMT_OP_SET_DISCOVERABLE:
1092 err = set_discoverable(sk, buf + sizeof(*hdr), len);
1093 break;
1094 case MGMT_OP_SET_CONNECTABLE:
1095 err = set_connectable(sk, buf + sizeof(*hdr), len);
1096 break;
1097 case MGMT_OP_SET_PAIRABLE:
1098 err = set_pairable(sk, buf + sizeof(*hdr), len);
1099 break;
1100 case MGMT_OP_ADD_UUID:
1101 err = add_uuid(sk, buf + sizeof(*hdr), len);
1102 break;
1103 case MGMT_OP_REMOVE_UUID:
1104 err = remove_uuid(sk, buf + sizeof(*hdr), len);
1105 break;
1106 case MGMT_OP_SET_DEV_CLASS:
1107 err = set_dev_class(sk, buf + sizeof(*hdr), len);
1108 break;
1109 case MGMT_OP_SET_SERVICE_CACHE:
1110 err = set_service_cache(sk, buf + sizeof(*hdr), len);
1111 break;
1112 case MGMT_OP_LOAD_KEYS:
1113 err = load_keys(sk, buf + sizeof(*hdr), len);
1114 break;
1115 case MGMT_OP_REMOVE_KEY:
1116 err = remove_key(sk, buf + sizeof(*hdr), len);
1117 break;
1118 case MGMT_OP_DISCONNECT:
1119 err = disconnect(sk, buf + sizeof(*hdr), len);
1120 break;
1121 case MGMT_OP_GET_CONNECTIONS:
1122 err = get_connections(sk, buf + sizeof(*hdr), len);
1123 break;
1124 case MGMT_OP_PIN_CODE_REPLY:
1125 err = pin_code_reply(sk, buf + sizeof(*hdr), len);
1126 break;
1127 case MGMT_OP_PIN_CODE_NEG_REPLY:
1128 err = pin_code_neg_reply(sk, buf + sizeof(*hdr), len);
1129 break;
1130 case MGMT_OP_SET_IO_CAPABILITY:
1131 err = set_io_capability(sk, buf + sizeof(*hdr), len);
1132 break;
253 default: 1133 default:
254 BT_DBG("Unknown op %u", opcode); 1134 BT_DBG("Unknown op %u", opcode);
255 err = cmd_status(sk, opcode, 0x01); 1135 err = cmd_status(sk, opcode, 0x01);
@@ -266,43 +1146,247 @@ done:
266 return err; 1146 return err;
267} 1147}
268 1148
269static int mgmt_event(u16 event, void *data, u16 data_len) 1149int mgmt_index_added(u16 index)
270{ 1150{
271 struct sk_buff *skb; 1151 struct mgmt_ev_index_added ev;
272 struct mgmt_hdr *hdr;
273 1152
274 skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC); 1153 put_unaligned_le16(index, &ev.index);
275 if (!skb)
276 return -ENOMEM;
277 1154
278 bt_cb(skb)->channel = HCI_CHANNEL_CONTROL; 1155 return mgmt_event(MGMT_EV_INDEX_ADDED, &ev, sizeof(ev), NULL);
1156}
279 1157
280 hdr = (void *) skb_put(skb, sizeof(*hdr)); 1158int mgmt_index_removed(u16 index)
281 hdr->opcode = cpu_to_le16(event); 1159{
282 hdr->len = cpu_to_le16(data_len); 1160 struct mgmt_ev_index_added ev;
283 1161
284 memcpy(skb_put(skb, data_len), data, data_len); 1162 put_unaligned_le16(index, &ev.index);
285 1163
286 hci_send_to_sock(NULL, skb); 1164 return mgmt_event(MGMT_EV_INDEX_REMOVED, &ev, sizeof(ev), NULL);
287 kfree_skb(skb); 1165}
288 1166
289 return 0; 1167struct cmd_lookup {
1168 u8 val;
1169 struct sock *sk;
1170};
1171
1172static void mode_rsp(struct pending_cmd *cmd, void *data)
1173{
1174 struct mgmt_mode *cp = cmd->cmd;
1175 struct cmd_lookup *match = data;
1176
1177 if (cp->val != match->val)
1178 return;
1179
1180 send_mode_rsp(cmd->sk, cmd->opcode, cmd->index, cp->val);
1181
1182 list_del(&cmd->list);
1183
1184 if (match->sk == NULL) {
1185 match->sk = cmd->sk;
1186 sock_hold(match->sk);
1187 }
1188
1189 mgmt_pending_free(cmd);
290} 1190}
291 1191
292int mgmt_index_added(u16 index) 1192int mgmt_powered(u16 index, u8 powered)
293{ 1193{
294 struct mgmt_ev_index_added ev; 1194 struct mgmt_mode ev;
1195 struct cmd_lookup match = { powered, NULL };
1196 int ret;
1197
1198 mgmt_pending_foreach(MGMT_OP_SET_POWERED, index, mode_rsp, &match);
295 1199
296 put_unaligned_le16(index, &ev.index); 1200 put_unaligned_le16(index, &ev.index);
1201 ev.val = powered;
1202
1203 ret = mgmt_event(MGMT_EV_POWERED, &ev, sizeof(ev), match.sk);
297 1204
298 return mgmt_event(MGMT_EV_INDEX_ADDED, &ev, sizeof(ev)); 1205 if (match.sk)
1206 sock_put(match.sk);
1207
1208 return ret;
299} 1209}
300 1210
301int mgmt_index_removed(u16 index) 1211int mgmt_discoverable(u16 index, u8 discoverable)
302{ 1212{
303 struct mgmt_ev_index_added ev; 1213 struct mgmt_mode ev;
1214 struct cmd_lookup match = { discoverable, NULL };
1215 int ret;
1216
1217 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index,
1218 mode_rsp, &match);
1219
1220 put_unaligned_le16(index, &ev.index);
1221 ev.val = discoverable;
1222
1223 ret = mgmt_event(MGMT_EV_DISCOVERABLE, &ev, sizeof(ev), match.sk);
1224
1225 if (match.sk)
1226 sock_put(match.sk);
1227
1228 return ret;
1229}
1230
1231int mgmt_connectable(u16 index, u8 connectable)
1232{
1233 struct mgmt_mode ev;
1234 struct cmd_lookup match = { connectable, NULL };
1235 int ret;
1236
1237 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index, mode_rsp, &match);
1238
1239 put_unaligned_le16(index, &ev.index);
1240 ev.val = connectable;
1241
1242 ret = mgmt_event(MGMT_EV_CONNECTABLE, &ev, sizeof(ev), match.sk);
1243
1244 if (match.sk)
1245 sock_put(match.sk);
1246
1247 return ret;
1248}
1249
1250int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type)
1251{
1252 struct mgmt_ev_new_key ev;
1253
1254 memset(&ev, 0, sizeof(ev));
1255
1256 put_unaligned_le16(index, &ev.index);
1257
1258 bacpy(&ev.key.bdaddr, &key->bdaddr);
1259 ev.key.type = key->type;
1260 memcpy(ev.key.val, key->val, 16);
1261 ev.key.pin_len = key->pin_len;
1262 ev.old_key_type = old_key_type;
1263
1264 return mgmt_event(MGMT_EV_NEW_KEY, &ev, sizeof(ev), NULL);
1265}
1266
1267int mgmt_connected(u16 index, bdaddr_t *bdaddr)
1268{
1269 struct mgmt_ev_connected ev;
304 1270
305 put_unaligned_le16(index, &ev.index); 1271 put_unaligned_le16(index, &ev.index);
1272 bacpy(&ev.bdaddr, bdaddr);
306 1273
307 return mgmt_event(MGMT_EV_INDEX_REMOVED, &ev, sizeof(ev)); 1274 return mgmt_event(MGMT_EV_CONNECTED, &ev, sizeof(ev), NULL);
1275}
1276
1277static void disconnect_rsp(struct pending_cmd *cmd, void *data)
1278{
1279 struct mgmt_cp_disconnect *cp = cmd->cmd;
1280 struct sock **sk = data;
1281 struct mgmt_rp_disconnect rp;
1282
1283 put_unaligned_le16(cmd->index, &rp.index);
1284 bacpy(&rp.bdaddr, &cp->bdaddr);
1285
1286 cmd_complete(cmd->sk, MGMT_OP_DISCONNECT, &rp, sizeof(rp));
1287
1288 *sk = cmd->sk;
1289 sock_hold(*sk);
1290
1291 list_del(&cmd->list);
1292 mgmt_pending_free(cmd);
1293}
1294
1295int mgmt_disconnected(u16 index, bdaddr_t *bdaddr)
1296{
1297 struct mgmt_ev_disconnected ev;
1298 struct sock *sk = NULL;
1299 int err;
1300
1301 mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk);
1302
1303 put_unaligned_le16(index, &ev.index);
1304 bacpy(&ev.bdaddr, bdaddr);
1305
1306 err = mgmt_event(MGMT_EV_DISCONNECTED, &ev, sizeof(ev), sk);
1307
1308 if (sk)
1309 sock_put(sk);
1310
1311 return err;
1312}
1313
1314int mgmt_disconnect_failed(u16 index)
1315{
1316 struct pending_cmd *cmd;
1317 int err;
1318
1319 cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, index);
1320 if (!cmd)
1321 return -ENOENT;
1322
1323 err = cmd_status(cmd->sk, MGMT_OP_DISCONNECT, EIO);
1324
1325 list_del(&cmd->list);
1326 mgmt_pending_free(cmd);
1327
1328 return err;
1329}
1330
1331int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status)
1332{
1333 struct mgmt_ev_connect_failed ev;
1334
1335 put_unaligned_le16(index, &ev.index);
1336 bacpy(&ev.bdaddr, bdaddr);
1337 ev.status = status;
1338
1339 return mgmt_event(MGMT_EV_CONNECT_FAILED, &ev, sizeof(ev), NULL);
1340}
1341
1342int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr)
1343{
1344 struct mgmt_ev_pin_code_request ev;
1345
1346 put_unaligned_le16(index, &ev.index);
1347 bacpy(&ev.bdaddr, bdaddr);
1348
1349 return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, &ev, sizeof(ev), NULL);
1350}
1351
1352int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
1353{
1354 struct pending_cmd *cmd;
1355 int err;
1356
1357 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, index);
1358 if (!cmd)
1359 return -ENOENT;
1360
1361 if (status != 0)
1362 err = cmd_status(cmd->sk, MGMT_OP_PIN_CODE_REPLY, status);
1363 else
1364 err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_REPLY,
1365 bdaddr, sizeof(*bdaddr));
1366
1367 list_del(&cmd->list);
1368 mgmt_pending_free(cmd);
1369
1370 return err;
1371}
1372
1373int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
1374{
1375 struct pending_cmd *cmd;
1376 int err;
1377
1378 cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, index);
1379 if (!cmd)
1380 return -ENOENT;
1381
1382 if (status != 0)
1383 err = cmd_status(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY, status);
1384 else
1385 err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY,
1386 bdaddr, sizeof(*bdaddr));
1387
1388 list_del(&cmd->list);
1389 mgmt_pending_free(cmd);
1390
1391 return err;
308} 1392}