Bluetooth: Add send_mode_rsp convenience function for mgmt.c
[linux-2.6-block.git] / net / bluetooth / mgmt.c
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
25 #include <asm/uaccess.h>
26 #include <asm/unaligned.h>
27
28 #include <net/bluetooth/bluetooth.h>
29 #include <net/bluetooth/hci_core.h>
30 #include <net/bluetooth/mgmt.h>
31
32 #define MGMT_VERSION    0
33 #define MGMT_REVISION   1
34
35 struct pending_cmd {
36         struct list_head list;
37         __u16 opcode;
38         int index;
39         void *cmd;
40         struct sock *sk;
41 };
42
43 LIST_HEAD(cmd_list);
44
45 static int cmd_status(struct sock *sk, u16 cmd, u8 status)
46 {
47         struct sk_buff *skb;
48         struct mgmt_hdr *hdr;
49         struct mgmt_ev_cmd_status *ev;
50
51         BT_DBG("sock %p", sk);
52
53         skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC);
54         if (!skb)
55                 return -ENOMEM;
56
57         hdr = (void *) skb_put(skb, sizeof(*hdr));
58
59         hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS);
60         hdr->len = cpu_to_le16(sizeof(*ev));
61
62         ev = (void *) skb_put(skb, sizeof(*ev));
63         ev->status = status;
64         put_unaligned_le16(cmd, &ev->opcode);
65
66         if (sock_queue_rcv_skb(sk, skb) < 0)
67                 kfree_skb(skb);
68
69         return 0;
70 }
71
72 static int read_version(struct sock *sk)
73 {
74         struct sk_buff *skb;
75         struct mgmt_hdr *hdr;
76         struct mgmt_ev_cmd_complete *ev;
77         struct mgmt_rp_read_version *rp;
78
79         BT_DBG("sock %p", sk);
80
81         skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC);
82         if (!skb)
83                 return -ENOMEM;
84
85         hdr = (void *) skb_put(skb, sizeof(*hdr));
86         hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
87         hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp));
88
89         ev = (void *) skb_put(skb, sizeof(*ev));
90         put_unaligned_le16(MGMT_OP_READ_VERSION, &ev->opcode);
91
92         rp = (void *) skb_put(skb, sizeof(*rp));
93         rp->version = MGMT_VERSION;
94         put_unaligned_le16(MGMT_REVISION, &rp->revision);
95
96         if (sock_queue_rcv_skb(sk, skb) < 0)
97                 kfree_skb(skb);
98
99         return 0;
100 }
101
102 static int read_index_list(struct sock *sk)
103 {
104         struct sk_buff *skb;
105         struct mgmt_hdr *hdr;
106         struct mgmt_ev_cmd_complete *ev;
107         struct mgmt_rp_read_index_list *rp;
108         struct list_head *p;
109         size_t body_len;
110         u16 count;
111         int i;
112
113         BT_DBG("sock %p", sk);
114
115         read_lock(&hci_dev_list_lock);
116
117         count = 0;
118         list_for_each(p, &hci_dev_list) {
119                 count++;
120         }
121
122         body_len = sizeof(*ev) + sizeof(*rp) + (2 * count);
123         skb = alloc_skb(sizeof(*hdr) + body_len, GFP_ATOMIC);
124         if (!skb) {
125                 read_unlock(&hci_dev_list_lock);
126                 return -ENOMEM;
127         }
128
129         hdr = (void *) skb_put(skb, sizeof(*hdr));
130         hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
131         hdr->len = cpu_to_le16(body_len);
132
133         ev = (void *) skb_put(skb, sizeof(*ev));
134         put_unaligned_le16(MGMT_OP_READ_INDEX_LIST, &ev->opcode);
135
136         rp = (void *) skb_put(skb, sizeof(*rp) + (2 * count));
137         put_unaligned_le16(count, &rp->num_controllers);
138
139         i = 0;
140         list_for_each(p, &hci_dev_list) {
141                 struct hci_dev *d = list_entry(p, struct hci_dev, list);
142
143                 hci_del_off_timer(d);
144
145                 set_bit(HCI_MGMT, &d->flags);
146
147                 if (test_bit(HCI_SETUP, &d->flags))
148                         continue;
149
150                 put_unaligned_le16(d->id, &rp->index[i++]);
151                 BT_DBG("Added hci%u", d->id);
152         }
153
154         read_unlock(&hci_dev_list_lock);
155
156         if (sock_queue_rcv_skb(sk, skb) < 0)
157                 kfree_skb(skb);
158
159         return 0;
160 }
161
162 static int read_controller_info(struct sock *sk, unsigned char *data, u16 len)
163 {
164         struct sk_buff *skb;
165         struct mgmt_hdr *hdr;
166         struct mgmt_ev_cmd_complete *ev;
167         struct mgmt_rp_read_info *rp;
168         struct mgmt_cp_read_info *cp;
169         struct hci_dev *hdev;
170         u16 dev_id;
171
172         BT_DBG("sock %p", sk);
173
174         if (len != 2)
175                 return cmd_status(sk, MGMT_OP_READ_INFO, EINVAL);
176
177         skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC);
178         if (!skb)
179                 return -ENOMEM;
180
181         hdr = (void *) skb_put(skb, sizeof(*hdr));
182         hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
183         hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp));
184
185         ev = (void *) skb_put(skb, sizeof(*ev));
186         put_unaligned_le16(MGMT_OP_READ_INFO, &ev->opcode);
187
188         rp = (void *) skb_put(skb, sizeof(*rp));
189
190         cp = (void *) data;
191         dev_id = get_unaligned_le16(&cp->index);
192
193         BT_DBG("request for hci%u", dev_id);
194
195         hdev = hci_dev_get(dev_id);
196         if (!hdev) {
197                 kfree_skb(skb);
198                 return cmd_status(sk, MGMT_OP_READ_INFO, ENODEV);
199         }
200
201         hci_del_off_timer(hdev);
202
203         hci_dev_lock_bh(hdev);
204
205         set_bit(HCI_MGMT, &hdev->flags);
206
207         put_unaligned_le16(hdev->id, &rp->index);
208         rp->type = hdev->dev_type;
209
210         rp->powered = test_bit(HCI_UP, &hdev->flags);
211         rp->connectable = test_bit(HCI_PSCAN, &hdev->flags);
212         rp->discoverable = test_bit(HCI_ISCAN, &hdev->flags);
213         rp->pairable = test_bit(HCI_PSCAN, &hdev->flags);
214
215         if (test_bit(HCI_AUTH, &hdev->flags))
216                 rp->sec_mode = 3;
217         else if (hdev->ssp_mode > 0)
218                 rp->sec_mode = 4;
219         else
220                 rp->sec_mode = 2;
221
222         bacpy(&rp->bdaddr, &hdev->bdaddr);
223         memcpy(rp->features, hdev->features, 8);
224         memcpy(rp->dev_class, hdev->dev_class, 3);
225         put_unaligned_le16(hdev->manufacturer, &rp->manufacturer);
226         rp->hci_ver = hdev->hci_ver;
227         put_unaligned_le16(hdev->hci_rev, &rp->hci_rev);
228
229         hci_dev_unlock_bh(hdev);
230         hci_dev_put(hdev);
231
232         if (sock_queue_rcv_skb(sk, skb) < 0)
233                 kfree_skb(skb);
234
235         return 0;
236 }
237
238 static void mgmt_pending_free(struct pending_cmd *cmd)
239 {
240         sock_put(cmd->sk);
241         kfree(cmd->cmd);
242         kfree(cmd);
243 }
244
245 static int mgmt_pending_add(struct sock *sk, u16 opcode, int index,
246                                                         void *data, u16 len)
247 {
248         struct pending_cmd *cmd;
249
250         cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
251         if (!cmd)
252                 return -ENOMEM;
253
254         cmd->opcode = opcode;
255         cmd->index = index;
256
257         cmd->cmd = kmalloc(len, GFP_ATOMIC);
258         if (!cmd->cmd) {
259                 kfree(cmd);
260                 return -ENOMEM;
261         }
262
263         memcpy(cmd->cmd, data, len);
264
265         cmd->sk = sk;
266         sock_hold(sk);
267
268         list_add(&cmd->list, &cmd_list);
269
270         return 0;
271 }
272
273 static void mgmt_pending_foreach(u16 opcode, int index,
274                                 void (*cb)(struct pending_cmd *cmd, void *data),
275                                 void *data)
276 {
277         struct list_head *p, *n;
278
279         list_for_each_safe(p, n, &cmd_list) {
280                 struct pending_cmd *cmd;
281
282                 cmd = list_entry(p, struct pending_cmd, list);
283
284                 if (cmd->opcode != opcode)
285                         continue;
286
287                 if (index >= 0 && cmd->index != index)
288                         continue;
289
290                 cb(cmd, data);
291         }
292 }
293
294 static struct pending_cmd *mgmt_pending_find(u16 opcode, int index)
295 {
296         struct list_head *p;
297
298         list_for_each(p, &cmd_list) {
299                 struct pending_cmd *cmd;
300
301                 cmd = list_entry(p, struct pending_cmd, list);
302
303                 if (cmd->opcode != opcode)
304                         continue;
305
306                 if (index >= 0 && cmd->index != index)
307                         continue;
308
309                 return cmd;
310         }
311
312         return NULL;
313 }
314
315 static void mgmt_pending_remove(u16 opcode, int index)
316 {
317         struct pending_cmd *cmd;
318
319         cmd = mgmt_pending_find(opcode, index);
320         if (cmd == NULL)
321                 return;
322
323         list_del(&cmd->list);
324         mgmt_pending_free(cmd);
325 }
326
327 static int set_powered(struct sock *sk, unsigned char *data, u16 len)
328 {
329         struct mgmt_mode *cp;
330         struct hci_dev *hdev;
331         u16 dev_id;
332         int ret, up;
333
334         cp = (void *) data;
335         dev_id = get_unaligned_le16(&cp->index);
336
337         BT_DBG("request for hci%u", dev_id);
338
339         hdev = hci_dev_get(dev_id);
340         if (!hdev)
341                 return cmd_status(sk, MGMT_OP_SET_POWERED, ENODEV);
342
343         hci_dev_lock_bh(hdev);
344
345         up = test_bit(HCI_UP, &hdev->flags);
346         if ((cp->val && up) || (!cp->val && !up)) {
347                 ret = cmd_status(sk, MGMT_OP_SET_POWERED, EALREADY);
348                 goto failed;
349         }
350
351         if (mgmt_pending_find(MGMT_OP_SET_POWERED, dev_id)) {
352                 ret = cmd_status(sk, MGMT_OP_SET_POWERED, EBUSY);
353                 goto failed;
354         }
355
356         ret = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, dev_id, data, len);
357         if (ret < 0)
358                 goto failed;
359
360         if (cp->val)
361                 queue_work(hdev->workqueue, &hdev->power_on);
362         else
363                 queue_work(hdev->workqueue, &hdev->power_off);
364
365         ret = 0;
366
367 failed:
368         hci_dev_unlock_bh(hdev);
369         hci_dev_put(hdev);
370         return ret;
371 }
372
373 static int set_discoverable(struct sock *sk, unsigned char *data, u16 len)
374 {
375         struct mgmt_mode *cp;
376         struct hci_dev *hdev;
377         u16 dev_id;
378         u8 scan;
379         int err;
380
381         cp = (void *) data;
382         dev_id = get_unaligned_le16(&cp->index);
383
384         BT_DBG("request for hci%u", dev_id);
385
386         hdev = hci_dev_get(dev_id);
387         if (!hdev)
388                 return cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, ENODEV);
389
390         hci_dev_lock_bh(hdev);
391
392         if (!test_bit(HCI_UP, &hdev->flags)) {
393                 err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, ENETDOWN);
394                 goto failed;
395         }
396
397         if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, dev_id) ||
398                         mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, dev_id)) {
399                 err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, EBUSY);
400                 goto failed;
401         }
402
403         if (cp->val == test_bit(HCI_ISCAN, &hdev->flags) &&
404                                         test_bit(HCI_PSCAN, &hdev->flags)) {
405                 err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, EALREADY);
406                 goto failed;
407         }
408
409         err = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, dev_id, data, len);
410         if (err < 0)
411                 goto failed;
412
413         scan = SCAN_PAGE;
414
415         if (cp->val)
416                 scan |= SCAN_INQUIRY;
417
418         err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
419         if (err < 0)
420                 mgmt_pending_remove(MGMT_OP_SET_DISCOVERABLE, dev_id);
421
422 failed:
423         hci_dev_unlock_bh(hdev);
424         hci_dev_put(hdev);
425
426         return err;
427 }
428
429 static int set_connectable(struct sock *sk, unsigned char *data, u16 len)
430 {
431         struct mgmt_mode *cp;
432         struct hci_dev *hdev;
433         u16 dev_id;
434         u8 scan;
435         int err;
436
437         cp = (void *) data;
438         dev_id = get_unaligned_le16(&cp->index);
439
440         BT_DBG("request for hci%u", dev_id);
441
442         hdev = hci_dev_get(dev_id);
443         if (!hdev)
444                 return cmd_status(sk, MGMT_OP_SET_CONNECTABLE, ENODEV);
445
446         hci_dev_lock_bh(hdev);
447
448         if (!test_bit(HCI_UP, &hdev->flags)) {
449                 err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, ENETDOWN);
450                 goto failed;
451         }
452
453         if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, dev_id) ||
454                         mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, dev_id)) {
455                 err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, EBUSY);
456                 goto failed;
457         }
458
459         if (cp->val == test_bit(HCI_PSCAN, &hdev->flags)) {
460                 err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, EALREADY);
461                 goto failed;
462         }
463
464         err = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, dev_id, data, len);
465         if (err < 0)
466                 goto failed;
467
468         if (cp->val)
469                 scan = SCAN_PAGE;
470         else
471                 scan = 0;
472
473         err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
474         if (err < 0)
475                 mgmt_pending_remove(MGMT_OP_SET_CONNECTABLE, dev_id);
476
477 failed:
478         hci_dev_unlock_bh(hdev);
479         hci_dev_put(hdev);
480
481         return err;
482 }
483
484 static int send_mode_rsp(struct sock *sk, u16 opcode, u16 index, u8 val)
485 {
486         struct mgmt_hdr *hdr;
487         struct mgmt_ev_cmd_complete *ev;
488         struct mgmt_mode *rp;
489         struct sk_buff *skb;
490
491         skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC);
492         if (!skb)
493                 return -ENOMEM;
494
495         hdr = (void *) skb_put(skb, sizeof(*hdr));
496         hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
497         hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp));
498
499         ev = (void *) skb_put(skb, sizeof(*ev));
500         put_unaligned_le16(opcode, &ev->opcode);
501
502         rp = (void *) skb_put(skb, sizeof(*rp));
503         put_unaligned_le16(index, &rp->index);
504         rp->val = val;
505
506         if (sock_queue_rcv_skb(sk, skb) < 0)
507                 kfree_skb(skb);
508
509         return 0;
510 }
511
512 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
513 {
514         unsigned char *buf;
515         struct mgmt_hdr *hdr;
516         u16 opcode, len;
517         int err;
518
519         BT_DBG("got %zu bytes", msglen);
520
521         if (msglen < sizeof(*hdr))
522                 return -EINVAL;
523
524         buf = kmalloc(msglen, GFP_ATOMIC);
525         if (!buf)
526                 return -ENOMEM;
527
528         if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
529                 err = -EFAULT;
530                 goto done;
531         }
532
533         hdr = (struct mgmt_hdr *) buf;
534         opcode = get_unaligned_le16(&hdr->opcode);
535         len = get_unaligned_le16(&hdr->len);
536
537         if (len != msglen - sizeof(*hdr)) {
538                 err = -EINVAL;
539                 goto done;
540         }
541
542         switch (opcode) {
543         case MGMT_OP_READ_VERSION:
544                 err = read_version(sk);
545                 break;
546         case MGMT_OP_READ_INDEX_LIST:
547                 err = read_index_list(sk);
548                 break;
549         case MGMT_OP_READ_INFO:
550                 err = read_controller_info(sk, buf + sizeof(*hdr), len);
551                 break;
552         case MGMT_OP_SET_POWERED:
553                 err = set_powered(sk, buf + sizeof(*hdr), len);
554                 break;
555         case MGMT_OP_SET_DISCOVERABLE:
556                 err = set_discoverable(sk, buf + sizeof(*hdr), len);
557                 break;
558         case MGMT_OP_SET_CONNECTABLE:
559                 err = set_connectable(sk, buf + sizeof(*hdr), len);
560                 break;
561         default:
562                 BT_DBG("Unknown op %u", opcode);
563                 err = cmd_status(sk, opcode, 0x01);
564                 break;
565         }
566
567         if (err < 0)
568                 goto done;
569
570         err = msglen;
571
572 done:
573         kfree(buf);
574         return err;
575 }
576
577 static int mgmt_event(u16 event, void *data, u16 data_len, struct sock *skip_sk)
578 {
579         struct sk_buff *skb;
580         struct mgmt_hdr *hdr;
581
582         skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC);
583         if (!skb)
584                 return -ENOMEM;
585
586         bt_cb(skb)->channel = HCI_CHANNEL_CONTROL;
587
588         hdr = (void *) skb_put(skb, sizeof(*hdr));
589         hdr->opcode = cpu_to_le16(event);
590         hdr->len = cpu_to_le16(data_len);
591
592         memcpy(skb_put(skb, data_len), data, data_len);
593
594         hci_send_to_sock(NULL, skb, skip_sk);
595         kfree_skb(skb);
596
597         return 0;
598 }
599
600 int mgmt_index_added(u16 index)
601 {
602         struct mgmt_ev_index_added ev;
603
604         put_unaligned_le16(index, &ev.index);
605
606         return mgmt_event(MGMT_EV_INDEX_ADDED, &ev, sizeof(ev), NULL);
607 }
608
609 int mgmt_index_removed(u16 index)
610 {
611         struct mgmt_ev_index_added ev;
612
613         put_unaligned_le16(index, &ev.index);
614
615         return mgmt_event(MGMT_EV_INDEX_REMOVED, &ev, sizeof(ev), NULL);
616 }
617
618 struct cmd_lookup {
619         u8 val;
620         struct sock *sk;
621 };
622
623 static void mode_rsp(struct pending_cmd *cmd, void *data)
624 {
625         struct mgmt_mode *cp = cmd->cmd;
626         struct cmd_lookup *match = data;
627
628         if (cp->val != match->val)
629                 return;
630
631         send_mode_rsp(cmd->sk, cmd->opcode, cmd->index, cp->val);
632
633         list_del(&cmd->list);
634
635         if (match->sk == NULL) {
636                 match->sk = cmd->sk;
637                 sock_hold(match->sk);
638         }
639
640         mgmt_pending_free(cmd);
641 }
642
643 int mgmt_powered(u16 index, u8 powered)
644 {
645         struct mgmt_mode ev;
646         struct cmd_lookup match = { powered, NULL };
647         int ret;
648
649         mgmt_pending_foreach(MGMT_OP_SET_POWERED, index, mode_rsp, &match);
650
651         put_unaligned_le16(index, &ev.index);
652         ev.val = powered;
653
654         ret = mgmt_event(MGMT_EV_POWERED, &ev, sizeof(ev), match.sk);
655
656         if (match.sk)
657                 sock_put(match.sk);
658
659         return ret;
660 }
661
662 int mgmt_discoverable(u16 index, u8 discoverable)
663 {
664         struct mgmt_mode ev;
665         struct cmd_lookup match = { discoverable, NULL };
666         int ret;
667
668         mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index,
669                                                         mode_rsp, &match);
670
671         put_unaligned_le16(index, &ev.index);
672         ev.val = discoverable;
673
674         ret = mgmt_event(MGMT_EV_DISCOVERABLE, &ev, sizeof(ev), match.sk);
675
676         if (match.sk)
677                 sock_put(match.sk);
678
679         return ret;
680 }
681
682 int mgmt_connectable(u16 index, u8 connectable)
683 {
684         struct mgmt_mode ev;
685         struct cmd_lookup match = { connectable, NULL };
686         int ret;
687
688         mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index, mode_rsp, &match);
689
690         put_unaligned_le16(index, &ev.index);
691         ev.val = connectable;
692
693         ret = mgmt_event(MGMT_EV_CONNECTABLE, &ev, sizeof(ev), match.sk);
694
695         if (match.sk)
696                 sock_put(match.sk);
697
698         return ret;
699 }