aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2011-01-26 06:07:10 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-02-07 22:40:05 -0500
commit053f0211d3b1a991f06a7b4aec5b762e42d7c6a4 (patch)
tree346f16fe1eac7dac9a8637e814ac83c45297a613
parentebc99feba7378349e2bfae7018af062767382f6c (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>
-rw-r--r--net/bluetooth/mgmt.c50
1 files changed, 29 insertions, 21 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 5f871b385a27..13872ae219c9 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
484static 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
484int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) 512int 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
595static void mode_rsp(struct pending_cmd *cmd, void *data) 623static 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