2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2010 Nokia Corporation
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;
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.
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.
23 /* Bluetooth HCI Management interface */
25 #include <asm/uaccess.h>
26 #include <asm/unaligned.h>
28 #include <net/bluetooth/bluetooth.h>
29 #include <net/bluetooth/hci_core.h>
30 #include <net/bluetooth/mgmt.h>
32 #define MGMT_VERSION 0
33 #define MGMT_REVISION 1
36 struct list_head list;
45 static int cmd_status(struct sock *sk, u16 cmd, u8 status)
49 struct mgmt_ev_cmd_status *ev;
51 BT_DBG("sock %p", sk);
53 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC);
57 hdr = (void *) skb_put(skb, sizeof(*hdr));
59 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS);
60 hdr->len = cpu_to_le16(sizeof(*ev));
62 ev = (void *) skb_put(skb, sizeof(*ev));
64 put_unaligned_le16(cmd, &ev->opcode);
66 if (sock_queue_rcv_skb(sk, skb) < 0)
72 static int read_version(struct sock *sk)
76 struct mgmt_ev_cmd_complete *ev;
77 struct mgmt_rp_read_version *rp;
79 BT_DBG("sock %p", sk);
81 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC);
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));
89 ev = (void *) skb_put(skb, sizeof(*ev));
90 put_unaligned_le16(MGMT_OP_READ_VERSION, &ev->opcode);
92 rp = (void *) skb_put(skb, sizeof(*rp));
93 rp->version = MGMT_VERSION;
94 put_unaligned_le16(MGMT_REVISION, &rp->revision);
96 if (sock_queue_rcv_skb(sk, skb) < 0)
102 static int read_index_list(struct sock *sk)
105 struct mgmt_hdr *hdr;
106 struct mgmt_ev_cmd_complete *ev;
107 struct mgmt_rp_read_index_list *rp;
113 BT_DBG("sock %p", sk);
115 read_lock(&hci_dev_list_lock);
118 list_for_each(p, &hci_dev_list) {
122 body_len = sizeof(*ev) + sizeof(*rp) + (2 * count);
123 skb = alloc_skb(sizeof(*hdr) + body_len, GFP_ATOMIC);
125 read_unlock(&hci_dev_list_lock);
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);
133 ev = (void *) skb_put(skb, sizeof(*ev));
134 put_unaligned_le16(MGMT_OP_READ_INDEX_LIST, &ev->opcode);
136 rp = (void *) skb_put(skb, sizeof(*rp) + (2 * count));
137 put_unaligned_le16(count, &rp->num_controllers);
140 list_for_each(p, &hci_dev_list) {
141 struct hci_dev *d = list_entry(p, struct hci_dev, list);
143 hci_del_off_timer(d);
145 if (test_bit(HCI_SETUP, &d->flags))
148 put_unaligned_le16(d->id, &rp->index[i++]);
149 BT_DBG("Added hci%u", d->id);
152 read_unlock(&hci_dev_list_lock);
154 if (sock_queue_rcv_skb(sk, skb) < 0)
160 static int read_controller_info(struct sock *sk, unsigned char *data, u16 len)
163 struct mgmt_hdr *hdr;
164 struct mgmt_ev_cmd_complete *ev;
165 struct mgmt_rp_read_info *rp;
166 struct mgmt_cp_read_info *cp;
167 struct hci_dev *hdev;
170 BT_DBG("sock %p", sk);
173 return cmd_status(sk, MGMT_OP_READ_INFO, EINVAL);
175 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC);
179 hdr = (void *) skb_put(skb, sizeof(*hdr));
180 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
181 hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp));
183 ev = (void *) skb_put(skb, sizeof(*ev));
184 put_unaligned_le16(MGMT_OP_READ_INFO, &ev->opcode);
186 rp = (void *) skb_put(skb, sizeof(*rp));
189 dev_id = get_unaligned_le16(&cp->index);
191 BT_DBG("request for hci%u", dev_id);
193 hdev = hci_dev_get(dev_id);
196 return cmd_status(sk, MGMT_OP_READ_INFO, ENODEV);
199 hci_del_off_timer(hdev);
201 hci_dev_lock_bh(hdev);
203 put_unaligned_le16(hdev->id, &rp->index);
204 rp->type = hdev->dev_type;
206 rp->powered = test_bit(HCI_UP, &hdev->flags);
207 rp->connectable = test_bit(HCI_PSCAN, &hdev->flags);
208 rp->discoverable = test_bit(HCI_ISCAN, &hdev->flags);
209 rp->pairable = test_bit(HCI_PSCAN, &hdev->flags);
211 if (test_bit(HCI_AUTH, &hdev->flags))
213 else if (hdev->ssp_mode > 0)
218 bacpy(&rp->bdaddr, &hdev->bdaddr);
219 memcpy(rp->features, hdev->features, 8);
220 memcpy(rp->dev_class, hdev->dev_class, 3);
221 put_unaligned_le16(hdev->manufacturer, &rp->manufacturer);
222 rp->hci_ver = hdev->hci_ver;
223 put_unaligned_le16(hdev->hci_rev, &rp->hci_rev);
225 hci_dev_unlock_bh(hdev);
228 if (sock_queue_rcv_skb(sk, skb) < 0)
234 static void mgmt_pending_free(struct pending_cmd *cmd)
241 static int mgmt_pending_add(struct sock *sk, u16 opcode, int index,
244 struct pending_cmd *cmd;
246 cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
250 cmd->opcode = opcode;
253 cmd->cmd = kmalloc(len, GFP_ATOMIC);
259 memcpy(cmd->cmd, data, len);
264 list_add(&cmd->list, &cmd_list);
269 static void mgmt_pending_foreach(u16 opcode, int index,
270 void (*cb)(struct pending_cmd *cmd, void *data),
273 struct list_head *p, *n;
275 list_for_each_safe(p, n, &cmd_list) {
276 struct pending_cmd *cmd;
278 cmd = list_entry(p, struct pending_cmd, list);
280 if (cmd->opcode != opcode)
283 if (index >= 0 && cmd->index != index)
290 static struct pending_cmd *mgmt_pending_find(u16 opcode, int index)
294 list_for_each(p, &cmd_list) {
295 struct pending_cmd *cmd;
297 cmd = list_entry(p, struct pending_cmd, list);
299 if (cmd->opcode != opcode)
302 if (index >= 0 && cmd->index != index)
311 static void mgmt_pending_remove(u16 opcode, int index)
313 struct pending_cmd *cmd;
315 cmd = mgmt_pending_find(opcode, index);
319 list_del(&cmd->list);
320 mgmt_pending_free(cmd);
323 static int set_powered(struct sock *sk, unsigned char *data, u16 len)
325 struct mgmt_cp_set_powered *cp;
326 struct hci_dev *hdev;
331 dev_id = get_unaligned_le16(&cp->index);
333 BT_DBG("request for hci%u", dev_id);
335 hdev = hci_dev_get(dev_id);
337 return cmd_status(sk, MGMT_OP_SET_POWERED, ENODEV);
339 hci_dev_lock_bh(hdev);
341 up = test_bit(HCI_UP, &hdev->flags);
342 if ((cp->powered && up) || (!cp->powered && !up)) {
343 ret = cmd_status(sk, MGMT_OP_SET_POWERED, EALREADY);
347 if (mgmt_pending_find(MGMT_OP_SET_POWERED, dev_id)) {
348 ret = cmd_status(sk, MGMT_OP_SET_POWERED, EBUSY);
352 ret = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, dev_id, data, len);
357 queue_work(hdev->workqueue, &hdev->power_on);
359 queue_work(hdev->workqueue, &hdev->power_off);
364 hci_dev_unlock_bh(hdev);
369 static int set_discoverable(struct sock *sk, unsigned char *data, u16 len)
371 struct mgmt_cp_set_discoverable *cp;
372 struct hci_dev *hdev;
378 dev_id = get_unaligned_le16(&cp->index);
380 BT_DBG("request for hci%u", dev_id);
382 hdev = hci_dev_get(dev_id);
384 return cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, ENODEV);
386 hci_dev_lock_bh(hdev);
388 if (!test_bit(HCI_UP, &hdev->flags)) {
389 err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, ENETDOWN);
393 if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, dev_id) ||
394 mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, dev_id)) {
395 err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, EBUSY);
399 if (cp->discoverable == test_bit(HCI_ISCAN, &hdev->flags) &&
400 test_bit(HCI_PSCAN, &hdev->flags)) {
401 err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, EALREADY);
405 err = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, dev_id, data, len);
411 if (cp->discoverable)
412 scan |= SCAN_INQUIRY;
414 err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
416 mgmt_pending_remove(MGMT_OP_SET_DISCOVERABLE, dev_id);
419 hci_dev_unlock_bh(hdev);
425 static int set_connectable(struct sock *sk, unsigned char *data, u16 len)
427 struct mgmt_cp_set_connectable *cp;
428 struct hci_dev *hdev;
434 dev_id = get_unaligned_le16(&cp->index);
436 BT_DBG("request for hci%u", dev_id);
438 hdev = hci_dev_get(dev_id);
440 return cmd_status(sk, MGMT_OP_SET_CONNECTABLE, ENODEV);
442 hci_dev_lock_bh(hdev);
444 if (!test_bit(HCI_UP, &hdev->flags)) {
445 err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, ENETDOWN);
449 if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, dev_id) ||
450 mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, dev_id)) {
451 err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, EBUSY);
455 if (cp->connectable == test_bit(HCI_PSCAN, &hdev->flags)) {
456 err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, EALREADY);
460 err = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, dev_id, data, len);
469 err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
471 mgmt_pending_remove(MGMT_OP_SET_CONNECTABLE, dev_id);
474 hci_dev_unlock_bh(hdev);
480 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
483 struct mgmt_hdr *hdr;
487 BT_DBG("got %zu bytes", msglen);
489 if (msglen < sizeof(*hdr))
492 buf = kmalloc(msglen, GFP_ATOMIC);
496 if (memcpy_fromiovec(buf, msg->msg_iov, msglen)) {
501 hdr = (struct mgmt_hdr *) buf;
502 opcode = get_unaligned_le16(&hdr->opcode);
503 len = get_unaligned_le16(&hdr->len);
505 if (len != msglen - sizeof(*hdr)) {
511 case MGMT_OP_READ_VERSION:
512 err = read_version(sk);
514 case MGMT_OP_READ_INDEX_LIST:
515 err = read_index_list(sk);
517 case MGMT_OP_READ_INFO:
518 err = read_controller_info(sk, buf + sizeof(*hdr), len);
520 case MGMT_OP_SET_POWERED:
521 err = set_powered(sk, buf + sizeof(*hdr), len);
523 case MGMT_OP_SET_DISCOVERABLE:
524 err = set_discoverable(sk, buf + sizeof(*hdr), len);
526 case MGMT_OP_SET_CONNECTABLE:
527 err = set_connectable(sk, buf + sizeof(*hdr), len);
530 BT_DBG("Unknown op %u", opcode);
531 err = cmd_status(sk, opcode, 0x01);
545 static int mgmt_event(u16 event, void *data, u16 data_len, struct sock *skip_sk)
548 struct mgmt_hdr *hdr;
550 skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC);
554 bt_cb(skb)->channel = HCI_CHANNEL_CONTROL;
556 hdr = (void *) skb_put(skb, sizeof(*hdr));
557 hdr->opcode = cpu_to_le16(event);
558 hdr->len = cpu_to_le16(data_len);
560 memcpy(skb_put(skb, data_len), data, data_len);
562 hci_send_to_sock(NULL, skb, skip_sk);
568 int mgmt_index_added(u16 index)
570 struct mgmt_ev_index_added ev;
572 put_unaligned_le16(index, &ev.index);
574 return mgmt_event(MGMT_EV_INDEX_ADDED, &ev, sizeof(ev), NULL);
577 int mgmt_index_removed(u16 index)
579 struct mgmt_ev_index_added ev;
581 put_unaligned_le16(index, &ev.index);
583 return mgmt_event(MGMT_EV_INDEX_REMOVED, &ev, sizeof(ev), NULL);
591 static void power_rsp(struct pending_cmd *cmd, void *data)
593 struct mgmt_hdr *hdr;
594 struct mgmt_ev_cmd_complete *ev;
595 struct mgmt_rp_set_powered *rp;
596 struct mgmt_cp_set_powered *cp = cmd->cmd;
598 struct cmd_lookup *match = data;
600 if (cp->powered != match->value)
603 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC);
607 hdr = (void *) skb_put(skb, sizeof(*hdr));
608 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
609 hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp));
611 ev = (void *) skb_put(skb, sizeof(*ev));
612 put_unaligned_le16(cmd->opcode, &ev->opcode);
614 rp = (void *) skb_put(skb, sizeof(*rp));
615 put_unaligned_le16(cmd->index, &rp->index);
616 rp->powered = cp->powered;
618 if (sock_queue_rcv_skb(cmd->sk, skb) < 0)
621 list_del(&cmd->list);
623 if (match->sk == NULL) {
625 sock_hold(match->sk);
628 mgmt_pending_free(cmd);
631 int mgmt_powered(u16 index, u8 powered)
633 struct mgmt_ev_powered ev;
634 struct cmd_lookup match = { powered, NULL };
637 put_unaligned_le16(index, &ev.index);
638 ev.powered = powered;
640 mgmt_pending_foreach(MGMT_OP_SET_POWERED, index, power_rsp, &match);
642 ret = mgmt_event(MGMT_EV_POWERED, &ev, sizeof(ev), match.sk);
650 static void discoverable_rsp(struct pending_cmd *cmd, void *data)
652 struct mgmt_cp_set_discoverable *cp = cmd->cmd;
653 struct cmd_lookup *match = data;
655 struct mgmt_hdr *hdr;
656 struct mgmt_ev_cmd_complete *ev;
657 struct mgmt_rp_set_discoverable *rp;
659 if (cp->discoverable != match->value)
662 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC);
666 hdr = (void *) skb_put(skb, sizeof(*hdr));
667 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
668 hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp));
670 ev = (void *) skb_put(skb, sizeof(*ev));
671 put_unaligned_le16(MGMT_OP_SET_DISCOVERABLE, &ev->opcode);
673 rp = (void *) skb_put(skb, sizeof(*rp));
674 put_unaligned_le16(cmd->index, &rp->index);
675 rp->discoverable = cp->discoverable;
677 if (sock_queue_rcv_skb(cmd->sk, skb) < 0)
680 list_del(&cmd->list);
682 if (match->sk == NULL) {
684 sock_hold(match->sk);
687 mgmt_pending_free(cmd);
690 int mgmt_discoverable(u16 index, u8 discoverable)
692 struct mgmt_ev_discoverable ev;
693 struct cmd_lookup match = { discoverable, NULL };
696 put_unaligned_le16(index, &ev.index);
697 ev.discoverable = discoverable;
699 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index,
700 discoverable_rsp, &match);
702 ret = mgmt_event(MGMT_EV_DISCOVERABLE, &ev, sizeof(ev), match.sk);
710 static void connectable_rsp(struct pending_cmd *cmd, void *data)
712 struct mgmt_cp_set_connectable *cp = cmd->cmd;
713 struct cmd_lookup *match = data;
715 struct mgmt_hdr *hdr;
716 struct mgmt_ev_cmd_complete *ev;
717 struct mgmt_rp_set_connectable *rp;
719 if (cp->connectable != match->value)
722 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC);
726 hdr = (void *) skb_put(skb, sizeof(*hdr));
727 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
728 hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp));
730 ev = (void *) skb_put(skb, sizeof(*ev));
731 put_unaligned_le16(MGMT_OP_SET_CONNECTABLE, &ev->opcode);
733 rp = (void *) skb_put(skb, sizeof(*rp));
734 put_unaligned_le16(cmd->index, &rp->index);
735 rp->connectable = cp->connectable;
737 if (sock_queue_rcv_skb(cmd->sk, skb) < 0)
740 list_del(&cmd->list);
742 if (match->sk == NULL) {
744 sock_hold(match->sk);
747 mgmt_pending_free(cmd);
750 int mgmt_connectable(u16 index, u8 connectable)
752 struct mgmt_ev_connectable ev;
753 struct cmd_lookup match = { connectable, NULL };
756 put_unaligned_le16(index, &ev.index);
757 ev.connectable = connectable;
759 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index,
760 connectable_rsp, &match);
762 ret = mgmt_event(MGMT_EV_CONNECTABLE, &ev, sizeof(ev), match.sk);