aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-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