aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2015-04-02 06:41:12 -0400
committerMarcel Holtmann <marcel@holtmann.org>2015-04-02 10:09:28 -0400
commit757aa0b56da5d1089c55bf349fa15836dae22b6f (patch)
tree7d5b7dd93801eaac90f3c8323ebf1a033349db6e /net/bluetooth
parentabe66a4d036933c7376b40b0d7bb5de0458331aa (diff)
Bluetooth: Move hci_get_cmd_complete() to hci_event.c
To make the hci_req_run_skb() API consistent with hci_cmd_sync_ev() the callback should receive the cmd_complete parameters in the 'normal' case and the full HCI event if a special event was expected. This patch moves the hci_get_cmd_complete() function from hci_core.c to hci_event.c where it's used to strip the skb from the needed headers before passing it on to the callback. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_core.c52
-rw-r--r--net/bluetooth/hci_event.c57
2 files changed, 58 insertions, 51 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index fda23720e7b8..46b114c0140b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -166,53 +166,6 @@ static void hci_req_cancel(struct hci_dev *hdev, int err)
166 } 166 }
167} 167}
168 168
169static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
170 u8 event, struct sk_buff *skb)
171{
172 struct hci_ev_cmd_complete *ev;
173 struct hci_event_hdr *hdr;
174
175 if (!skb)
176 return ERR_PTR(-ENODATA);
177
178 if (skb->len < sizeof(*hdr)) {
179 BT_ERR("Too short HCI event");
180 goto failed;
181 }
182
183 hdr = (void *) skb->data;
184 skb_pull(skb, HCI_EVENT_HDR_SIZE);
185
186 if (event) {
187 if (hdr->evt != event)
188 goto failed;
189 return skb;
190 }
191
192 if (hdr->evt != HCI_EV_CMD_COMPLETE) {
193 BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
194 goto failed;
195 }
196
197 if (skb->len < sizeof(*ev)) {
198 BT_ERR("Too short cmd_complete event");
199 goto failed;
200 }
201
202 ev = (void *) skb->data;
203 skb_pull(skb, sizeof(*ev));
204
205 if (opcode == __le16_to_cpu(ev->opcode))
206 return skb;
207
208 BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
209 __le16_to_cpu(ev->opcode));
210
211failed:
212 kfree_skb(skb);
213 return ERR_PTR(-ENODATA);
214}
215
216struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, 169struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
217 const void *param, u8 event, u32 timeout) 170 const void *param, u8 event, u32 timeout)
218{ 171{
@@ -271,7 +224,10 @@ struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
271 return ERR_PTR(err); 224 return ERR_PTR(err);
272 } 225 }
273 226
274 return hci_get_cmd_complete(hdev, opcode, event, skb); 227 if (!skb)
228 return ERR_PTR(-ENODATA);
229
230 return skb;
275} 231}
276EXPORT_SYMBOL(__hci_cmd_sync_ev); 232EXPORT_SYMBOL(__hci_cmd_sync_ev);
277 233
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index dc9547c11c45..c2483cb6ffbd 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -5043,13 +5043,58 @@ static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
5043 amp_read_loc_assoc_final_data(hdev, hcon); 5043 amp_read_loc_assoc_final_data(hdev, hcon);
5044} 5044}
5045 5045
5046static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
5047 u8 event, struct sk_buff *skb)
5048{
5049 struct hci_ev_cmd_complete *ev;
5050 struct hci_event_hdr *hdr;
5051
5052 if (!skb)
5053 return false;
5054
5055 if (skb->len < sizeof(*hdr)) {
5056 BT_ERR("Too short HCI event");
5057 return false;
5058 }
5059
5060 hdr = (void *) skb->data;
5061 skb_pull(skb, HCI_EVENT_HDR_SIZE);
5062
5063 if (event) {
5064 if (hdr->evt != event)
5065 return false;
5066 return true;
5067 }
5068
5069 if (hdr->evt != HCI_EV_CMD_COMPLETE) {
5070 BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
5071 return false;
5072 }
5073
5074 if (skb->len < sizeof(*ev)) {
5075 BT_ERR("Too short cmd_complete event");
5076 return false;
5077 }
5078
5079 ev = (void *) skb->data;
5080 skb_pull(skb, sizeof(*ev));
5081
5082 if (opcode != __le16_to_cpu(ev->opcode)) {
5083 BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode,
5084 __le16_to_cpu(ev->opcode));
5085 return false;
5086 }
5087
5088 return true;
5089}
5090
5046void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) 5091void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
5047{ 5092{
5048 struct hci_event_hdr *hdr = (void *) skb->data; 5093 struct hci_event_hdr *hdr = (void *) skb->data;
5049 hci_req_complete_t req_complete = NULL; 5094 hci_req_complete_t req_complete = NULL;
5050 hci_req_complete_skb_t req_complete_skb = NULL; 5095 hci_req_complete_skb_t req_complete_skb = NULL;
5051 struct sk_buff *orig_skb = NULL; 5096 struct sk_buff *orig_skb = NULL;
5052 u8 status = 0, event = hdr->evt; 5097 u8 status = 0, event = hdr->evt, req_evt = 0;
5053 u16 opcode = HCI_OP_NOP; 5098 u16 opcode = HCI_OP_NOP;
5054 5099
5055 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) { 5100 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
@@ -5057,6 +5102,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
5057 opcode = __le16_to_cpu(cmd_hdr->opcode); 5102 opcode = __le16_to_cpu(cmd_hdr->opcode);
5058 hci_req_cmd_complete(hdev, opcode, status, &req_complete, 5103 hci_req_cmd_complete(hdev, opcode, status, &req_complete,
5059 &req_complete_skb); 5104 &req_complete_skb);
5105 req_evt = event;
5060 } 5106 }
5061 5107
5062 /* If it looks like we might end up having to call 5108 /* If it looks like we might end up having to call
@@ -5250,10 +5296,15 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
5250 break; 5296 break;
5251 } 5297 }
5252 5298
5253 if (req_complete) 5299 if (req_complete) {
5254 req_complete(hdev, status, opcode); 5300 req_complete(hdev, status, opcode);
5255 else if (req_complete_skb) 5301 } else if (req_complete_skb) {
5302 if (!hci_get_cmd_complete(hdev, opcode, req_evt, orig_skb)) {
5303 kfree_skb(orig_skb);
5304 orig_skb = NULL;
5305 }
5256 req_complete_skb(hdev, status, opcode, orig_skb); 5306 req_complete_skb(hdev, status, opcode, orig_skb);
5307 }
5257 5308
5258 kfree_skb(orig_skb); 5309 kfree_skb(orig_skb);
5259 kfree_skb(skb); 5310 kfree_skb(skb);