diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2011-01-26 06:07:10 -0500 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-02-07 22:40:05 -0500 |
commit | 053f0211d3b1a991f06a7b4aec5b762e42d7c6a4 (patch) | |
tree | 346f16fe1eac7dac9a8637e814ac83c45297a613 /net/bluetooth/mgmt.c | |
parent | ebc99feba7378349e2bfae7018af062767382f6c (diff) |
Bluetooth: Add send_mode_rsp convenience function for mgmt.c
Several management commands have similar responses but they are not
always sent asynchronously. To enable synchronous sending (from the
managment command handler function) a send_mode_rsp function is added.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r-- | net/bluetooth/mgmt.c | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 5f871b385a2..13872ae219c 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -481,6 +481,34 @@ failed: | |||
481 | return err; | 481 | return err; |
482 | } | 482 | } |
483 | 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 | |||
484 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | 512 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) |
485 | { | 513 | { |
486 | unsigned char *buf; | 514 | unsigned char *buf; |
@@ -594,33 +622,13 @@ struct cmd_lookup { | |||
594 | 622 | ||
595 | static void mode_rsp(struct pending_cmd *cmd, void *data) | 623 | static void mode_rsp(struct pending_cmd *cmd, void *data) |
596 | { | 624 | { |
597 | struct mgmt_hdr *hdr; | ||
598 | struct mgmt_ev_cmd_complete *ev; | ||
599 | struct mgmt_mode *rp; | ||
600 | struct mgmt_mode *cp = cmd->cmd; | 625 | struct mgmt_mode *cp = cmd->cmd; |
601 | struct sk_buff *skb; | ||
602 | struct cmd_lookup *match = data; | 626 | struct cmd_lookup *match = data; |
603 | 627 | ||
604 | if (cp->val != match->val) | 628 | if (cp->val != match->val) |
605 | return; | 629 | return; |
606 | 630 | ||
607 | skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC); | 631 | send_mode_rsp(cmd->sk, cmd->opcode, cmd->index, cp->val); |
608 | if (!skb) | ||
609 | return; | ||
610 | |||
611 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | ||
612 | hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); | ||
613 | hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp)); | ||
614 | |||
615 | ev = (void *) skb_put(skb, sizeof(*ev)); | ||
616 | put_unaligned_le16(cmd->opcode, &ev->opcode); | ||
617 | |||
618 | rp = (void *) skb_put(skb, sizeof(*rp)); | ||
619 | put_unaligned_le16(cmd->index, &rp->index); | ||
620 | rp->val = cp->val; | ||
621 | |||
622 | if (sock_queue_rcv_skb(cmd->sk, skb) < 0) | ||
623 | kfree_skb(skb); | ||
624 | 632 | ||
625 | list_del(&cmd->list); | 633 | list_del(&cmd->list); |
626 | 634 | ||