d10735076a25c389c25b7c202de2dc233a2ff274
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 set_bit(HCI_MGMT
, &d
->flags
);
147 if (test_bit(HCI_SETUP
, &d
->flags
))
150 put_unaligned_le16(d
->id
, &rp
->index
[i
++]);
151 BT_DBG("Added hci%u", d
->id
);
154 read_unlock(&hci_dev_list_lock
);
156 if (sock_queue_rcv_skb(sk
, skb
) < 0)
162 static int read_controller_info(struct sock
*sk
, unsigned char *data
, u16 len
)
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
;
172 BT_DBG("sock %p", sk
);
175 return cmd_status(sk
, MGMT_OP_READ_INFO
, EINVAL
);
177 skb
= alloc_skb(sizeof(*hdr
) + sizeof(*ev
) + sizeof(*rp
), GFP_ATOMIC
);
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
));
185 ev
= (void *) skb_put(skb
, sizeof(*ev
));
186 put_unaligned_le16(MGMT_OP_READ_INFO
, &ev
->opcode
);
188 rp
= (void *) skb_put(skb
, sizeof(*rp
));
191 dev_id
= get_unaligned_le16(&cp
->index
);
193 BT_DBG("request for hci%u", dev_id
);
195 hdev
= hci_dev_get(dev_id
);
198 return cmd_status(sk
, MGMT_OP_READ_INFO
, ENODEV
);
201 hci_del_off_timer(hdev
);
203 hci_dev_lock_bh(hdev
);
205 set_bit(HCI_MGMT
, &hdev
->flags
);
207 put_unaligned_le16(hdev
->id
, &rp
->index
);
208 rp
->type
= hdev
->dev_type
;
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
);
215 if (test_bit(HCI_AUTH
, &hdev
->flags
))
217 else if (hdev
->ssp_mode
> 0)
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
);
229 hci_dev_unlock_bh(hdev
);
232 if (sock_queue_rcv_skb(sk
, skb
) < 0)
238 static void mgmt_pending_free(struct pending_cmd
*cmd
)
245 static int mgmt_pending_add(struct sock
*sk
, u16 opcode
, int index
,
248 struct pending_cmd
*cmd
;
250 cmd
= kmalloc(sizeof(*cmd
), GFP_ATOMIC
);
254 cmd
->opcode
= opcode
;
257 cmd
->cmd
= kmalloc(len
, GFP_ATOMIC
);
263 memcpy(cmd
->cmd
, data
, len
);
268 list_add(&cmd
->list
, &cmd_list
);
273 static void mgmt_pending_foreach(u16 opcode
, int index
,
274 void (*cb
)(struct pending_cmd
*cmd
, void *data
),
277 struct list_head
*p
, *n
;
279 list_for_each_safe(p
, n
, &cmd_list
) {
280 struct pending_cmd
*cmd
;
282 cmd
= list_entry(p
, struct pending_cmd
, list
);
284 if (cmd
->opcode
!= opcode
)
287 if (index
>= 0 && cmd
->index
!= index
)
294 static struct pending_cmd
*mgmt_pending_find(u16 opcode
, int index
)
298 list_for_each(p
, &cmd_list
) {
299 struct pending_cmd
*cmd
;
301 cmd
= list_entry(p
, struct pending_cmd
, list
);
303 if (cmd
->opcode
!= opcode
)
306 if (index
>= 0 && cmd
->index
!= index
)
315 static void mgmt_pending_remove(u16 opcode
, int index
)
317 struct pending_cmd
*cmd
;
319 cmd
= mgmt_pending_find(opcode
, index
);
323 list_del(&cmd
->list
);
324 mgmt_pending_free(cmd
);
327 static int set_powered(struct sock
*sk
, unsigned char *data
, u16 len
)
329 struct mgmt_mode
*cp
;
330 struct hci_dev
*hdev
;
335 dev_id
= get_unaligned_le16(&cp
->index
);
337 BT_DBG("request for hci%u", dev_id
);
339 hdev
= hci_dev_get(dev_id
);
341 return cmd_status(sk
, MGMT_OP_SET_POWERED
, ENODEV
);
343 hci_dev_lock_bh(hdev
);
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
);
351 if (mgmt_pending_find(MGMT_OP_SET_POWERED
, dev_id
)) {
352 ret
= cmd_status(sk
, MGMT_OP_SET_POWERED
, EBUSY
);
356 ret
= mgmt_pending_add(sk
, MGMT_OP_SET_POWERED
, dev_id
, data
, len
);
361 queue_work(hdev
->workqueue
, &hdev
->power_on
);
363 queue_work(hdev
->workqueue
, &hdev
->power_off
);
368 hci_dev_unlock_bh(hdev
);
373 static int set_discoverable(struct sock
*sk
, unsigned char *data
, u16 len
)
375 struct mgmt_mode
*cp
;
376 struct hci_dev
*hdev
;
382 dev_id
= get_unaligned_le16(&cp
->index
);
384 BT_DBG("request for hci%u", dev_id
);
386 hdev
= hci_dev_get(dev_id
);
388 return cmd_status(sk
, MGMT_OP_SET_DISCOVERABLE
, ENODEV
);
390 hci_dev_lock_bh(hdev
);
392 if (!test_bit(HCI_UP
, &hdev
->flags
)) {
393 err
= cmd_status(sk
, MGMT_OP_SET_DISCOVERABLE
, ENETDOWN
);
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
);
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
);
409 err
= mgmt_pending_add(sk
, MGMT_OP_SET_DISCOVERABLE
, dev_id
, data
, len
);
416 scan
|= SCAN_INQUIRY
;
418 err
= hci_send_cmd(hdev
, HCI_OP_WRITE_SCAN_ENABLE
, 1, &scan
);
420 mgmt_pending_remove(MGMT_OP_SET_DISCOVERABLE
, dev_id
);
423 hci_dev_unlock_bh(hdev
);
429 static int set_connectable(struct sock
*sk
, unsigned char *data
, u16 len
)
431 struct mgmt_mode
*cp
;
432 struct hci_dev
*hdev
;
438 dev_id
= get_unaligned_le16(&cp
->index
);
440 BT_DBG("request for hci%u", dev_id
);
442 hdev
= hci_dev_get(dev_id
);
444 return cmd_status(sk
, MGMT_OP_SET_CONNECTABLE
, ENODEV
);
446 hci_dev_lock_bh(hdev
);
448 if (!test_bit(HCI_UP
, &hdev
->flags
)) {
449 err
= cmd_status(sk
, MGMT_OP_SET_CONNECTABLE
, ENETDOWN
);
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
);
459 if (cp
->val
== test_bit(HCI_PSCAN
, &hdev
->flags
)) {
460 err
= cmd_status(sk
, MGMT_OP_SET_CONNECTABLE
, EALREADY
);
464 err
= mgmt_pending_add(sk
, MGMT_OP_SET_CONNECTABLE
, dev_id
, data
, len
);
473 err
= hci_send_cmd(hdev
, HCI_OP_WRITE_SCAN_ENABLE
, 1, &scan
);
475 mgmt_pending_remove(MGMT_OP_SET_CONNECTABLE
, dev_id
);
478 hci_dev_unlock_bh(hdev
);
484 static int mgmt_event(u16 event
, void *data
, u16 data_len
, struct sock
*skip_sk
)
487 struct mgmt_hdr
*hdr
;
489 skb
= alloc_skb(sizeof(*hdr
) + data_len
, GFP_ATOMIC
);
493 bt_cb(skb
)->channel
= HCI_CHANNEL_CONTROL
;
495 hdr
= (void *) skb_put(skb
, sizeof(*hdr
));
496 hdr
->opcode
= cpu_to_le16(event
);
497 hdr
->len
= cpu_to_le16(data_len
);
499 memcpy(skb_put(skb
, data_len
), data
, data_len
);
501 hci_send_to_sock(NULL
, skb
, skip_sk
);
507 static int send_mode_rsp(struct sock
*sk
, u16 opcode
, u16 index
, u8 val
)
509 struct mgmt_hdr
*hdr
;
510 struct mgmt_ev_cmd_complete
*ev
;
511 struct mgmt_mode
*rp
;
514 skb
= alloc_skb(sizeof(*hdr
) + sizeof(*ev
) + sizeof(*rp
), GFP_ATOMIC
);
518 hdr
= (void *) skb_put(skb
, sizeof(*hdr
));
519 hdr
->opcode
= cpu_to_le16(MGMT_EV_CMD_COMPLETE
);
520 hdr
->len
= cpu_to_le16(sizeof(*ev
) + sizeof(*rp
));
522 ev
= (void *) skb_put(skb
, sizeof(*ev
));
523 put_unaligned_le16(opcode
, &ev
->opcode
);
525 rp
= (void *) skb_put(skb
, sizeof(*rp
));
526 put_unaligned_le16(index
, &rp
->index
);
529 if (sock_queue_rcv_skb(sk
, skb
) < 0)
535 static int set_pairable(struct sock
*sk
, unsigned char *data
, u16 len
)
537 struct mgmt_mode
*cp
, ev
;
538 struct hci_dev
*hdev
;
543 dev_id
= get_unaligned_le16(&cp
->index
);
545 BT_DBG("request for hci%u", dev_id
);
547 hdev
= hci_dev_get(dev_id
);
549 return cmd_status(sk
, MGMT_OP_SET_PAIRABLE
, ENODEV
);
551 hci_dev_lock_bh(hdev
);
554 set_bit(HCI_PAIRABLE
, &hdev
->flags
);
556 clear_bit(HCI_PAIRABLE
, &hdev
->flags
);
558 err
= send_mode_rsp(sk
, MGMT_OP_SET_PAIRABLE
, dev_id
, cp
->val
);
562 put_unaligned_le16(dev_id
, &ev
.index
);
565 err
= mgmt_event(MGMT_EV_PAIRABLE
, &ev
, sizeof(ev
), sk
);
568 hci_dev_unlock_bh(hdev
);
574 int mgmt_control(struct sock
*sk
, struct msghdr
*msg
, size_t msglen
)
577 struct mgmt_hdr
*hdr
;
581 BT_DBG("got %zu bytes", msglen
);
583 if (msglen
< sizeof(*hdr
))
586 buf
= kmalloc(msglen
, GFP_ATOMIC
);
590 if (memcpy_fromiovec(buf
, msg
->msg_iov
, msglen
)) {
595 hdr
= (struct mgmt_hdr
*) buf
;
596 opcode
= get_unaligned_le16(&hdr
->opcode
);
597 len
= get_unaligned_le16(&hdr
->len
);
599 if (len
!= msglen
- sizeof(*hdr
)) {
605 case MGMT_OP_READ_VERSION
:
606 err
= read_version(sk
);
608 case MGMT_OP_READ_INDEX_LIST
:
609 err
= read_index_list(sk
);
611 case MGMT_OP_READ_INFO
:
612 err
= read_controller_info(sk
, buf
+ sizeof(*hdr
), len
);
614 case MGMT_OP_SET_POWERED
:
615 err
= set_powered(sk
, buf
+ sizeof(*hdr
), len
);
617 case MGMT_OP_SET_DISCOVERABLE
:
618 err
= set_discoverable(sk
, buf
+ sizeof(*hdr
), len
);
620 case MGMT_OP_SET_CONNECTABLE
:
621 err
= set_connectable(sk
, buf
+ sizeof(*hdr
), len
);
623 case MGMT_OP_SET_PAIRABLE
:
624 err
= set_pairable(sk
, buf
+ sizeof(*hdr
), len
);
627 BT_DBG("Unknown op %u", opcode
);
628 err
= cmd_status(sk
, opcode
, 0x01);
642 int mgmt_index_added(u16 index
)
644 struct mgmt_ev_index_added ev
;
646 put_unaligned_le16(index
, &ev
.index
);
648 return mgmt_event(MGMT_EV_INDEX_ADDED
, &ev
, sizeof(ev
), NULL
);
651 int mgmt_index_removed(u16 index
)
653 struct mgmt_ev_index_added ev
;
655 put_unaligned_le16(index
, &ev
.index
);
657 return mgmt_event(MGMT_EV_INDEX_REMOVED
, &ev
, sizeof(ev
), NULL
);
665 static void mode_rsp(struct pending_cmd
*cmd
, void *data
)
667 struct mgmt_mode
*cp
= cmd
->cmd
;
668 struct cmd_lookup
*match
= data
;
670 if (cp
->val
!= match
->val
)
673 send_mode_rsp(cmd
->sk
, cmd
->opcode
, cmd
->index
, cp
->val
);
675 list_del(&cmd
->list
);
677 if (match
->sk
== NULL
) {
679 sock_hold(match
->sk
);
682 mgmt_pending_free(cmd
);
685 int mgmt_powered(u16 index
, u8 powered
)
688 struct cmd_lookup match
= { powered
, NULL
};
691 mgmt_pending_foreach(MGMT_OP_SET_POWERED
, index
, mode_rsp
, &match
);
693 put_unaligned_le16(index
, &ev
.index
);
696 ret
= mgmt_event(MGMT_EV_POWERED
, &ev
, sizeof(ev
), match
.sk
);
704 int mgmt_discoverable(u16 index
, u8 discoverable
)
707 struct cmd_lookup match
= { discoverable
, NULL
};
710 mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE
, index
,
713 put_unaligned_le16(index
, &ev
.index
);
714 ev
.val
= discoverable
;
716 ret
= mgmt_event(MGMT_EV_DISCOVERABLE
, &ev
, sizeof(ev
), match
.sk
);
724 int mgmt_connectable(u16 index
, u8 connectable
)
727 struct cmd_lookup match
= { connectable
, NULL
};
730 mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE
, index
, mode_rsp
, &match
);
732 put_unaligned_le16(index
, &ev
.index
);
733 ev
.val
= connectable
;
735 ret
= mgmt_event(MGMT_EV_CONNECTABLE
, &ev
, sizeof(ev
), match
.sk
);
This page took 0.045396 seconds and 4 git commands to generate.