aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2011-01-21 23:46:43 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-02-07 22:40:07 -0500
commita38528f1117590169c0bf61cbf874e9fd2d5c5c9 (patch)
tree17ba6ef8d6b00cc81c83bbd969832fed3088004f /net/bluetooth/mgmt.c
parent2784eb41b1fbb3ff80f4921fe9dbb4c4acb6dc24 (diff)
Bluetooth: Create common cmd_complete function for mgmt.c
A lot of management code needs to generate command complete events so it makes sense to have a helper function for this. 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.c227
1 files changed, 67 insertions, 160 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 8f4f47e9d5c9..005288b2a58e 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -69,29 +69,26 @@ static int cmd_status(struct sock *sk, u16 cmd, u8 status)
69 return 0; 69 return 0;
70} 70}
71 71
72static int read_version(struct sock *sk) 72static int cmd_complete(struct sock *sk, u16 cmd, void *rp, size_t rp_len)
73{ 73{
74 struct sk_buff *skb; 74 struct sk_buff *skb;
75 struct mgmt_hdr *hdr; 75 struct mgmt_hdr *hdr;
76 struct mgmt_ev_cmd_complete *ev; 76 struct mgmt_ev_cmd_complete *ev;
77 struct mgmt_rp_read_version *rp;
78 77
79 BT_DBG("sock %p", sk); 78 BT_DBG("sock %p", sk);
80 79
81 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC); 80 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_ATOMIC);
82 if (!skb) 81 if (!skb)
83 return -ENOMEM; 82 return -ENOMEM;
84 83
85 hdr = (void *) skb_put(skb, sizeof(*hdr)); 84 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));
88 85
89 ev = (void *) skb_put(skb, sizeof(*ev)); 86 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
90 put_unaligned_le16(MGMT_OP_READ_VERSION, &ev->opcode); 87 hdr->len = cpu_to_le16(sizeof(*ev) + rp_len);
91 88
92 rp = (void *) skb_put(skb, sizeof(*rp)); 89 ev = (void *) skb_put(skb, sizeof(*ev) + rp_len);
93 rp->version = MGMT_VERSION; 90 put_unaligned_le16(cmd, &ev->opcode);
94 put_unaligned_le16(MGMT_REVISION, &rp->revision); 91 memcpy(ev->data, rp, rp_len);
95 92
96 if (sock_queue_rcv_skb(sk, skb) < 0) 93 if (sock_queue_rcv_skb(sk, skb) < 0)
97 kfree_skb(skb); 94 kfree_skb(skb);
@@ -99,16 +96,25 @@ static int read_version(struct sock *sk)
99 return 0; 96 return 0;
100} 97}
101 98
99static int read_version(struct sock *sk)
100{
101 struct mgmt_rp_read_version rp;
102
103 BT_DBG("sock %p", sk);
104
105 rp.version = MGMT_VERSION;
106 put_unaligned_le16(MGMT_REVISION, &rp.revision);
107
108 return cmd_complete(sk, MGMT_OP_READ_VERSION, &rp, sizeof(rp));
109}
110
102static int read_index_list(struct sock *sk) 111static int read_index_list(struct sock *sk)
103{ 112{
104 struct sk_buff *skb;
105 struct mgmt_hdr *hdr;
106 struct mgmt_ev_cmd_complete *ev;
107 struct mgmt_rp_read_index_list *rp; 113 struct mgmt_rp_read_index_list *rp;
108 struct list_head *p; 114 struct list_head *p;
109 size_t body_len; 115 size_t rp_len;
110 u16 count; 116 u16 count;
111 int i; 117 int i, err;
112 118
113 BT_DBG("sock %p", sk); 119 BT_DBG("sock %p", sk);
114 120
@@ -119,21 +125,13 @@ static int read_index_list(struct sock *sk)
119 count++; 125 count++;
120 } 126 }
121 127
122 body_len = sizeof(*ev) + sizeof(*rp) + (2 * count); 128 rp_len = sizeof(*rp) + (2 * count);
123 skb = alloc_skb(sizeof(*hdr) + body_len, GFP_ATOMIC); 129 rp = kmalloc(rp_len, GFP_ATOMIC);
124 if (!skb) { 130 if (!rp) {
125 read_unlock(&hci_dev_list_lock); 131 read_unlock(&hci_dev_list_lock);
126 return -ENOMEM; 132 return -ENOMEM;
127 } 133 }
128 134
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);
132
133 ev = (void *) skb_put(skb, sizeof(*ev));
134 put_unaligned_le16(MGMT_OP_READ_INDEX_LIST, &ev->opcode);
135
136 rp = (void *) skb_put(skb, sizeof(*rp) + (2 * count));
137 put_unaligned_le16(count, &rp->num_controllers); 135 put_unaligned_le16(count, &rp->num_controllers);
138 136
139 i = 0; 137 i = 0;
@@ -153,19 +151,17 @@ static int read_index_list(struct sock *sk)
153 151
154 read_unlock(&hci_dev_list_lock); 152 read_unlock(&hci_dev_list_lock);
155 153
156 if (sock_queue_rcv_skb(sk, skb) < 0) 154 err = cmd_complete(sk, MGMT_OP_READ_INDEX_LIST, rp, rp_len);
157 kfree_skb(skb);
158 155
159 return 0; 156 kfree(rp);
157
158 return err;
160} 159}
161 160
162static int read_controller_info(struct sock *sk, unsigned char *data, u16 len) 161static int read_controller_info(struct sock *sk, unsigned char *data, u16 len)
163{ 162{
164 struct sk_buff *skb; 163 struct mgmt_rp_read_info rp;
165 struct mgmt_hdr *hdr; 164 struct mgmt_cp_read_info *cp = (void *) data;
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; 165 struct hci_dev *hdev;
170 u16 dev_id; 166 u16 dev_id;
171 167
@@ -174,29 +170,13 @@ static int read_controller_info(struct sock *sk, unsigned char *data, u16 len)
174 if (len != 2) 170 if (len != 2)
175 return cmd_status(sk, MGMT_OP_READ_INFO, EINVAL); 171 return cmd_status(sk, MGMT_OP_READ_INFO, EINVAL);
176 172
177 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC);
178 if (!skb)
179 return -ENOMEM;
180
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));
184
185 ev = (void *) skb_put(skb, sizeof(*ev));
186 put_unaligned_le16(MGMT_OP_READ_INFO, &ev->opcode);
187
188 rp = (void *) skb_put(skb, sizeof(*rp));
189
190 cp = (void *) data;
191 dev_id = get_unaligned_le16(&cp->index); 173 dev_id = get_unaligned_le16(&cp->index);
192 174
193 BT_DBG("request for hci%u", dev_id); 175 BT_DBG("request for hci%u", dev_id);
194 176
195 hdev = hci_dev_get(dev_id); 177 hdev = hci_dev_get(dev_id);
196 if (!hdev) { 178 if (!hdev)
197 kfree_skb(skb);
198 return cmd_status(sk, MGMT_OP_READ_INFO, ENODEV); 179 return cmd_status(sk, MGMT_OP_READ_INFO, ENODEV);
199 }
200 180
201 hci_del_off_timer(hdev); 181 hci_del_off_timer(hdev);
202 182
@@ -204,35 +184,32 @@ static int read_controller_info(struct sock *sk, unsigned char *data, u16 len)
204 184
205 set_bit(HCI_MGMT, &hdev->flags); 185 set_bit(HCI_MGMT, &hdev->flags);
206 186
207 put_unaligned_le16(hdev->id, &rp->index); 187 put_unaligned_le16(hdev->id, &rp.index);
208 rp->type = hdev->dev_type; 188 rp.type = hdev->dev_type;
209 189
210 rp->powered = test_bit(HCI_UP, &hdev->flags); 190 rp.powered = test_bit(HCI_UP, &hdev->flags);
211 rp->connectable = test_bit(HCI_PSCAN, &hdev->flags); 191 rp.connectable = test_bit(HCI_PSCAN, &hdev->flags);
212 rp->discoverable = test_bit(HCI_ISCAN, &hdev->flags); 192 rp.discoverable = test_bit(HCI_ISCAN, &hdev->flags);
213 rp->pairable = test_bit(HCI_PSCAN, &hdev->flags); 193 rp.pairable = test_bit(HCI_PSCAN, &hdev->flags);
214 194
215 if (test_bit(HCI_AUTH, &hdev->flags)) 195 if (test_bit(HCI_AUTH, &hdev->flags))
216 rp->sec_mode = 3; 196 rp.sec_mode = 3;
217 else if (hdev->ssp_mode > 0) 197 else if (hdev->ssp_mode > 0)
218 rp->sec_mode = 4; 198 rp.sec_mode = 4;
219 else 199 else
220 rp->sec_mode = 2; 200 rp.sec_mode = 2;
221 201
222 bacpy(&rp->bdaddr, &hdev->bdaddr); 202 bacpy(&rp.bdaddr, &hdev->bdaddr);
223 memcpy(rp->features, hdev->features, 8); 203 memcpy(rp.features, hdev->features, 8);
224 memcpy(rp->dev_class, hdev->dev_class, 3); 204 memcpy(rp.dev_class, hdev->dev_class, 3);
225 put_unaligned_le16(hdev->manufacturer, &rp->manufacturer); 205 put_unaligned_le16(hdev->manufacturer, &rp.manufacturer);
226 rp->hci_ver = hdev->hci_ver; 206 rp.hci_ver = hdev->hci_ver;
227 put_unaligned_le16(hdev->hci_rev, &rp->hci_rev); 207 put_unaligned_le16(hdev->hci_rev, &rp.hci_rev);
228 208
229 hci_dev_unlock_bh(hdev); 209 hci_dev_unlock_bh(hdev);
230 hci_dev_put(hdev); 210 hci_dev_put(hdev);
231 211
232 if (sock_queue_rcv_skb(sk, skb) < 0) 212 return cmd_complete(sk, MGMT_OP_READ_INFO, &rp, sizeof(rp));
233 kfree_skb(skb);
234
235 return 0;
236} 213}
237 214
238static void mgmt_pending_free(struct pending_cmd *cmd) 215static void mgmt_pending_free(struct pending_cmd *cmd)
@@ -506,30 +483,12 @@ static int mgmt_event(u16 event, void *data, u16 data_len, struct sock *skip_sk)
506 483
507static int send_mode_rsp(struct sock *sk, u16 opcode, u16 index, u8 val) 484static int send_mode_rsp(struct sock *sk, u16 opcode, u16 index, u8 val)
508{ 485{
509 struct mgmt_hdr *hdr; 486 struct mgmt_mode rp;
510 struct mgmt_ev_cmd_complete *ev;
511 struct mgmt_mode *rp;
512 struct sk_buff *skb;
513 487
514 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC); 488 put_unaligned_le16(index, &rp.index);
515 if (!skb) 489 rp.val = val;
516 return -ENOMEM;
517 490
518 hdr = (void *) skb_put(skb, sizeof(*hdr)); 491 return cmd_complete(sk, opcode, &rp, sizeof(rp));
519 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
520 hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp));
521
522 ev = (void *) skb_put(skb, sizeof(*ev));
523 put_unaligned_le16(opcode, &ev->opcode);
524
525 rp = (void *) skb_put(skb, sizeof(*rp));
526 put_unaligned_le16(index, &rp->index);
527 rp->val = val;
528
529 if (sock_queue_rcv_skb(sk, skb) < 0)
530 kfree_skb(skb);
531
532 return 0;
533} 492}
534 493
535static int set_pairable(struct sock *sk, unsigned char *data, u16 len) 494static int set_pairable(struct sock *sk, unsigned char *data, u16 len)
@@ -571,31 +530,6 @@ failed:
571 return err; 530 return err;
572} 531}
573 532
574static int index_rsp(struct sock *sk, u16 opcode, u16 index)
575{
576 struct mgmt_hdr *hdr;
577 struct mgmt_ev_cmd_complete *ev;
578 struct sk_buff *skb;
579
580 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(index), GFP_ATOMIC);
581 if (!skb)
582 return -ENOMEM;
583
584 hdr = (void *) skb_put(skb, sizeof(*hdr));
585 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
586 hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(index));
587
588 ev = (void *) skb_put(skb, sizeof(*ev));
589 put_unaligned_le16(opcode, &ev->opcode);
590
591 put_unaligned_le16(index, skb_put(skb, sizeof(index)));
592
593 if (sock_queue_rcv_skb(sk, skb) < 0)
594 kfree_skb(skb);
595
596 return 0;
597}
598
599static u8 get_service_classes(struct hci_dev *hdev) 533static u8 get_service_classes(struct hci_dev *hdev)
600{ 534{
601 struct list_head *p; 535 struct list_head *p;
@@ -663,7 +597,7 @@ static int add_uuid(struct sock *sk, unsigned char *data, u16 len)
663 if (err < 0) 597 if (err < 0)
664 goto failed; 598 goto failed;
665 599
666 err = index_rsp(sk, MGMT_OP_ADD_UUID, dev_id); 600 err = cmd_complete(sk, MGMT_OP_ADD_UUID, &dev_id, sizeof(dev_id));
667 601
668failed: 602failed:
669 hci_dev_unlock_bh(hdev); 603 hci_dev_unlock_bh(hdev);
@@ -718,7 +652,7 @@ static int remove_uuid(struct sock *sk, unsigned char *data, u16 len)
718 if (err < 0) 652 if (err < 0)
719 goto unlock; 653 goto unlock;
720 654
721 err = index_rsp(sk, MGMT_OP_REMOVE_UUID, dev_id); 655 err = cmd_complete(sk, MGMT_OP_REMOVE_UUID, &dev_id, sizeof(dev_id));
722 656
723unlock: 657unlock:
724 hci_dev_unlock_bh(hdev); 658 hci_dev_unlock_bh(hdev);
@@ -751,7 +685,8 @@ static int set_dev_class(struct sock *sk, unsigned char *data, u16 len)
751 err = update_class(hdev); 685 err = update_class(hdev);
752 686
753 if (err == 0) 687 if (err == 0)
754 err = index_rsp(sk, MGMT_OP_SET_DEV_CLASS, dev_id); 688 err = cmd_complete(sk, MGMT_OP_SET_DEV_CLASS, &dev_id,
689 sizeof(dev_id));
755 690
756 hci_dev_unlock_bh(hdev); 691 hci_dev_unlock_bh(hdev);
757 hci_dev_put(hdev); 692 hci_dev_put(hdev);
@@ -786,7 +721,8 @@ static int set_service_cache(struct sock *sk, unsigned char *data, u16 len)
786 } 721 }
787 722
788 if (err == 0) 723 if (err == 0)
789 err = index_rsp(sk, MGMT_OP_SET_SERVICE_CACHE, dev_id); 724 err = cmd_complete(sk, MGMT_OP_SET_SERVICE_CACHE, &dev_id,
725 sizeof(dev_id));
790 726
791 hci_dev_unlock_bh(hdev); 727 hci_dev_unlock_bh(hdev);
792 hci_dev_put(hdev); 728 hci_dev_put(hdev);
@@ -943,14 +879,11 @@ failed:
943 879
944static int get_connections(struct sock *sk, unsigned char *data, u16 len) 880static int get_connections(struct sock *sk, unsigned char *data, u16 len)
945{ 881{
946 struct sk_buff *skb;
947 struct mgmt_hdr *hdr;
948 struct mgmt_cp_get_connections *cp; 882 struct mgmt_cp_get_connections *cp;
949 struct mgmt_ev_cmd_complete *ev;
950 struct mgmt_rp_get_connections *rp; 883 struct mgmt_rp_get_connections *rp;
951 struct hci_dev *hdev; 884 struct hci_dev *hdev;
952 struct list_head *p; 885 struct list_head *p;
953 size_t body_len; 886 size_t rp_len;
954 u16 dev_id, count; 887 u16 dev_id, count;
955 int i, err; 888 int i, err;
956 889
@@ -970,21 +903,13 @@ static int get_connections(struct sock *sk, unsigned char *data, u16 len)
970 count++; 903 count++;
971 } 904 }
972 905
973 body_len = sizeof(*ev) + sizeof(*rp) + (count * sizeof(bdaddr_t)); 906 rp_len = sizeof(*rp) + (count * sizeof(bdaddr_t));
974 skb = alloc_skb(sizeof(*hdr) + body_len, GFP_ATOMIC); 907 rp = kmalloc(rp_len, GFP_ATOMIC);
975 if (!skb) { 908 if (!rp) {
976 err = -ENOMEM; 909 err = -ENOMEM;
977 goto unlock; 910 goto unlock;
978 } 911 }
979 912
980 hdr = (void *) skb_put(skb, sizeof(*hdr));
981 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
982 hdr->len = cpu_to_le16(body_len);
983
984 ev = (void *) skb_put(skb, sizeof(*ev));
985 put_unaligned_le16(MGMT_OP_GET_CONNECTIONS, &ev->opcode);
986
987 rp = (void *) skb_put(skb, sizeof(*rp) + (count * sizeof(bdaddr_t)));
988 put_unaligned_le16(dev_id, &rp->index); 913 put_unaligned_le16(dev_id, &rp->index);
989 put_unaligned_le16(count, &rp->conn_count); 914 put_unaligned_le16(count, &rp->conn_count);
990 915
@@ -999,12 +924,10 @@ static int get_connections(struct sock *sk, unsigned char *data, u16 len)
999 924
1000 read_unlock(&hci_dev_list_lock); 925 read_unlock(&hci_dev_list_lock);
1001 926
1002 if (sock_queue_rcv_skb(sk, skb) < 0) 927 err = cmd_complete(sk, MGMT_OP_GET_CONNECTIONS, rp, rp_len);
1003 kfree_skb(skb);
1004
1005 err = 0;
1006 928
1007unlock: 929unlock:
930 kfree(rp);
1008 hci_dev_unlock_bh(hdev); 931 hci_dev_unlock_bh(hdev);
1009 hci_dev_put(hdev); 932 hci_dev_put(hdev);
1010 return err; 933 return err;
@@ -1234,28 +1157,12 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data)
1234{ 1157{
1235 struct mgmt_cp_disconnect *cp = cmd->cmd; 1158 struct mgmt_cp_disconnect *cp = cmd->cmd;
1236 struct sock **sk = data; 1159 struct sock **sk = data;
1237 struct sk_buff *skb; 1160 struct mgmt_rp_disconnect rp;
1238 struct mgmt_hdr *hdr;
1239 struct mgmt_ev_cmd_complete *ev;
1240 struct mgmt_rp_disconnect *rp;
1241 1161
1242 skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC); 1162 put_unaligned_le16(cmd->index, &rp.index);
1243 if (!skb) 1163 bacpy(&rp.bdaddr, &cp->bdaddr);
1244 return;
1245 1164
1246 hdr = (void *) skb_put(skb, sizeof(*hdr)); 1165 cmd_complete(cmd->sk, MGMT_OP_DISCONNECT, &rp, sizeof(rp));
1247 hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
1248 hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp));
1249
1250 ev = (void *) skb_put(skb, sizeof(*ev));
1251 put_unaligned_le16(MGMT_OP_DISCONNECT, &ev->opcode);
1252
1253 rp = (void *) skb_put(skb, sizeof(*rp));
1254 put_unaligned_le16(cmd->index, &rp->index);
1255 bacpy(&rp->bdaddr, &cp->bdaddr);
1256
1257 if (sock_queue_rcv_skb(cmd->sk, skb) < 0)
1258 kfree_skb(skb);
1259 1166
1260 *sk = cmd->sk; 1167 *sk = cmd->sk;
1261 sock_hold(*sk); 1168 sock_hold(*sk);