diff options
author | Arron Wang <arron.wang@intel.com> | 2015-07-24 05:10:50 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-07-30 07:37:22 -0400 |
commit | b3d3914006a05cae448684058760359ef0cded49 (patch) | |
tree | 5d5b10445028c2f143d3ad8d67c81b6177c984c5 /net/bluetooth | |
parent | 839278823c27b71b46d677c8cf56b2d1f95610af (diff) |
Bluetooth: Move amp assoc read/write completed callback to amp.c
To avoid amp module hooks from hci_event.c
Signed-off-by: Arron Wang <arron.wang@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/amp.c | 81 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 59 |
2 files changed, 77 insertions, 63 deletions
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c index ee016f039100..45888fad8362 100644 --- a/net/bluetooth/amp.c +++ b/net/bluetooth/amp.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <net/bluetooth/hci_core.h> | 16 | #include <net/bluetooth/hci_core.h> |
17 | #include <crypto/hash.h> | 17 | #include <crypto/hash.h> |
18 | 18 | ||
19 | #include "hci_request.h" | ||
19 | #include "a2mp.h" | 20 | #include "a2mp.h" |
20 | #include "amp.h" | 21 | #include "amp.h" |
21 | 22 | ||
@@ -220,10 +221,49 @@ int phylink_gen_key(struct hci_conn *conn, u8 *data, u8 *len, u8 *type) | |||
220 | return hmac_sha256(gamp_key, HCI_AMP_LINK_KEY_SIZE, "802b", 4, data); | 221 | return hmac_sha256(gamp_key, HCI_AMP_LINK_KEY_SIZE, "802b", 4, data); |
221 | } | 222 | } |
222 | 223 | ||
224 | static void read_local_amp_assoc_complete(struct hci_dev *hdev, u8 status, | ||
225 | u16 opcode, struct sk_buff *skb) | ||
226 | { | ||
227 | struct hci_rp_read_local_amp_assoc *rp = (void *)skb->data; | ||
228 | struct amp_assoc *assoc = &hdev->loc_assoc; | ||
229 | size_t rem_len, frag_len; | ||
230 | |||
231 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); | ||
232 | |||
233 | if (rp->status) | ||
234 | goto send_rsp; | ||
235 | |||
236 | frag_len = skb->len - sizeof(*rp); | ||
237 | rem_len = __le16_to_cpu(rp->rem_len); | ||
238 | |||
239 | if (rem_len > frag_len) { | ||
240 | BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len); | ||
241 | |||
242 | memcpy(assoc->data + assoc->offset, rp->frag, frag_len); | ||
243 | assoc->offset += frag_len; | ||
244 | |||
245 | /* Read other fragments */ | ||
246 | amp_read_loc_assoc_frag(hdev, rp->phy_handle); | ||
247 | |||
248 | return; | ||
249 | } | ||
250 | |||
251 | memcpy(assoc->data + assoc->offset, rp->frag, rem_len); | ||
252 | assoc->len = assoc->offset + rem_len; | ||
253 | assoc->offset = 0; | ||
254 | |||
255 | send_rsp: | ||
256 | /* Send A2MP Rsp when all fragments are received */ | ||
257 | a2mp_send_getampassoc_rsp(hdev, rp->status); | ||
258 | a2mp_send_create_phy_link_req(hdev, rp->status); | ||
259 | } | ||
260 | |||
223 | void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle) | 261 | void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle) |
224 | { | 262 | { |
225 | struct hci_cp_read_local_amp_assoc cp; | 263 | struct hci_cp_read_local_amp_assoc cp; |
226 | struct amp_assoc *loc_assoc = &hdev->loc_assoc; | 264 | struct amp_assoc *loc_assoc = &hdev->loc_assoc; |
265 | struct hci_request req; | ||
266 | int err = 0; | ||
227 | 267 | ||
228 | BT_DBG("%s handle %d", hdev->name, phy_handle); | 268 | BT_DBG("%s handle %d", hdev->name, phy_handle); |
229 | 269 | ||
@@ -231,12 +271,18 @@ void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle) | |||
231 | cp.max_len = cpu_to_le16(hdev->amp_assoc_size); | 271 | cp.max_len = cpu_to_le16(hdev->amp_assoc_size); |
232 | cp.len_so_far = cpu_to_le16(loc_assoc->offset); | 272 | cp.len_so_far = cpu_to_le16(loc_assoc->offset); |
233 | 273 | ||
234 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_ASSOC, sizeof(cp), &cp); | 274 | hci_req_init(&req, hdev); |
275 | hci_req_add(&req, HCI_OP_READ_LOCAL_AMP_ASSOC, sizeof(cp), &cp); | ||
276 | err = hci_req_run_skb(&req, read_local_amp_assoc_complete); | ||
277 | if (err < 0) | ||
278 | a2mp_send_getampassoc_rsp(hdev, A2MP_STATUS_INVALID_CTRL_ID); | ||
235 | } | 279 | } |
236 | 280 | ||
237 | void amp_read_loc_assoc(struct hci_dev *hdev, struct amp_mgr *mgr) | 281 | void amp_read_loc_assoc(struct hci_dev *hdev, struct amp_mgr *mgr) |
238 | { | 282 | { |
239 | struct hci_cp_read_local_amp_assoc cp; | 283 | struct hci_cp_read_local_amp_assoc cp; |
284 | struct hci_request req; | ||
285 | int err = 0; | ||
240 | 286 | ||
241 | memset(&hdev->loc_assoc, 0, sizeof(struct amp_assoc)); | 287 | memset(&hdev->loc_assoc, 0, sizeof(struct amp_assoc)); |
242 | memset(&cp, 0, sizeof(cp)); | 288 | memset(&cp, 0, sizeof(cp)); |
@@ -244,7 +290,11 @@ void amp_read_loc_assoc(struct hci_dev *hdev, struct amp_mgr *mgr) | |||
244 | cp.max_len = cpu_to_le16(hdev->amp_assoc_size); | 290 | cp.max_len = cpu_to_le16(hdev->amp_assoc_size); |
245 | 291 | ||
246 | set_bit(READ_LOC_AMP_ASSOC, &mgr->state); | 292 | set_bit(READ_LOC_AMP_ASSOC, &mgr->state); |
247 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_ASSOC, sizeof(cp), &cp); | 293 | hci_req_init(&req, hdev); |
294 | hci_req_add(&req, HCI_OP_READ_LOCAL_AMP_ASSOC, sizeof(cp), &cp); | ||
295 | hci_req_run_skb(&req, read_local_amp_assoc_complete); | ||
296 | if (err < 0) | ||
297 | a2mp_send_getampassoc_rsp(hdev, A2MP_STATUS_INVALID_CTRL_ID); | ||
248 | } | 298 | } |
249 | 299 | ||
250 | void amp_read_loc_assoc_final_data(struct hci_dev *hdev, | 300 | void amp_read_loc_assoc_final_data(struct hci_dev *hdev, |
@@ -252,6 +302,8 @@ void amp_read_loc_assoc_final_data(struct hci_dev *hdev, | |||
252 | { | 302 | { |
253 | struct hci_cp_read_local_amp_assoc cp; | 303 | struct hci_cp_read_local_amp_assoc cp; |
254 | struct amp_mgr *mgr = hcon->amp_mgr; | 304 | struct amp_mgr *mgr = hcon->amp_mgr; |
305 | struct hci_request req; | ||
306 | int err = 0; | ||
255 | 307 | ||
256 | cp.phy_handle = hcon->handle; | 308 | cp.phy_handle = hcon->handle; |
257 | cp.len_so_far = cpu_to_le16(0); | 309 | cp.len_so_far = cpu_to_le16(0); |
@@ -260,7 +312,25 @@ void amp_read_loc_assoc_final_data(struct hci_dev *hdev, | |||
260 | set_bit(READ_LOC_AMP_ASSOC_FINAL, &mgr->state); | 312 | set_bit(READ_LOC_AMP_ASSOC_FINAL, &mgr->state); |
261 | 313 | ||
262 | /* Read Local AMP Assoc final link information data */ | 314 | /* Read Local AMP Assoc final link information data */ |
263 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_ASSOC, sizeof(cp), &cp); | 315 | hci_req_init(&req, hdev); |
316 | hci_req_add(&req, HCI_OP_READ_LOCAL_AMP_ASSOC, sizeof(cp), &cp); | ||
317 | hci_req_run_skb(&req, read_local_amp_assoc_complete); | ||
318 | if (err < 0) | ||
319 | a2mp_send_getampassoc_rsp(hdev, A2MP_STATUS_INVALID_CTRL_ID); | ||
320 | } | ||
321 | |||
322 | static void write_remote_amp_assoc_complete(struct hci_dev *hdev, u8 status, | ||
323 | u16 opcode, struct sk_buff *skb) | ||
324 | { | ||
325 | struct hci_rp_write_remote_amp_assoc *rp = (void *)skb->data; | ||
326 | |||
327 | BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x", | ||
328 | hdev->name, rp->status, rp->phy_handle); | ||
329 | |||
330 | if (rp->status) | ||
331 | return; | ||
332 | |||
333 | amp_write_rem_assoc_continue(hdev, rp->phy_handle); | ||
264 | } | 334 | } |
265 | 335 | ||
266 | /* Write AMP Assoc data fragments, returns true with last fragment written*/ | 336 | /* Write AMP Assoc data fragments, returns true with last fragment written*/ |
@@ -270,6 +340,7 @@ static bool amp_write_rem_assoc_frag(struct hci_dev *hdev, | |||
270 | struct hci_cp_write_remote_amp_assoc *cp; | 340 | struct hci_cp_write_remote_amp_assoc *cp; |
271 | struct amp_mgr *mgr = hcon->amp_mgr; | 341 | struct amp_mgr *mgr = hcon->amp_mgr; |
272 | struct amp_ctrl *ctrl; | 342 | struct amp_ctrl *ctrl; |
343 | struct hci_request req; | ||
273 | u16 frag_len, len; | 344 | u16 frag_len, len; |
274 | 345 | ||
275 | ctrl = amp_ctrl_lookup(mgr, hcon->remote_id); | 346 | ctrl = amp_ctrl_lookup(mgr, hcon->remote_id); |
@@ -307,7 +378,9 @@ static bool amp_write_rem_assoc_frag(struct hci_dev *hdev, | |||
307 | 378 | ||
308 | amp_ctrl_put(ctrl); | 379 | amp_ctrl_put(ctrl); |
309 | 380 | ||
310 | hci_send_cmd(hdev, HCI_OP_WRITE_REMOTE_AMP_ASSOC, len, cp); | 381 | hci_req_init(&req, hdev); |
382 | hci_req_add(&req, HCI_OP_WRITE_REMOTE_AMP_ASSOC, sizeof(cp), &cp); | ||
383 | hci_req_run_skb(&req, write_remote_amp_assoc_complete); | ||
311 | 384 | ||
312 | kfree(cp); | 385 | kfree(cp); |
313 | 386 | ||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index a9a8e453817e..1ee01864569f 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -837,43 +837,6 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev, | |||
837 | hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); | 837 | hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); |
838 | } | 838 | } |
839 | 839 | ||
840 | static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev, | ||
841 | struct sk_buff *skb) | ||
842 | { | ||
843 | struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data; | ||
844 | struct amp_assoc *assoc = &hdev->loc_assoc; | ||
845 | size_t rem_len, frag_len; | ||
846 | |||
847 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); | ||
848 | |||
849 | if (rp->status) | ||
850 | goto a2mp_rsp; | ||
851 | |||
852 | frag_len = skb->len - sizeof(*rp); | ||
853 | rem_len = __le16_to_cpu(rp->rem_len); | ||
854 | |||
855 | if (rem_len > frag_len) { | ||
856 | BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len); | ||
857 | |||
858 | memcpy(assoc->data + assoc->offset, rp->frag, frag_len); | ||
859 | assoc->offset += frag_len; | ||
860 | |||
861 | /* Read other fragments */ | ||
862 | amp_read_loc_assoc_frag(hdev, rp->phy_handle); | ||
863 | |||
864 | return; | ||
865 | } | ||
866 | |||
867 | memcpy(assoc->data + assoc->offset, rp->frag, rem_len); | ||
868 | assoc->len = assoc->offset + rem_len; | ||
869 | assoc->offset = 0; | ||
870 | |||
871 | a2mp_rsp: | ||
872 | /* Send A2MP Rsp when all fragments are received */ | ||
873 | a2mp_send_getampassoc_rsp(hdev, rp->status); | ||
874 | a2mp_send_create_phy_link_req(hdev, rp->status); | ||
875 | } | ||
876 | |||
877 | static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, | 840 | static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, |
878 | struct sk_buff *skb) | 841 | struct sk_buff *skb) |
879 | { | 842 | { |
@@ -1406,20 +1369,6 @@ static void hci_cc_set_adv_param(struct hci_dev *hdev, struct sk_buff *skb) | |||
1406 | hci_dev_unlock(hdev); | 1369 | hci_dev_unlock(hdev); |
1407 | } | 1370 | } |
1408 | 1371 | ||
1409 | static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev, | ||
1410 | struct sk_buff *skb) | ||
1411 | { | ||
1412 | struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data; | ||
1413 | |||
1414 | BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x", | ||
1415 | hdev->name, rp->status, rp->phy_handle); | ||
1416 | |||
1417 | if (rp->status) | ||
1418 | return; | ||
1419 | |||
1420 | amp_write_rem_assoc_continue(hdev, rp->phy_handle); | ||
1421 | } | ||
1422 | |||
1423 | static void hci_cc_read_rssi(struct hci_dev *hdev, struct sk_buff *skb) | 1372 | static void hci_cc_read_rssi(struct hci_dev *hdev, struct sk_buff *skb) |
1424 | { | 1373 | { |
1425 | struct hci_rp_read_rssi *rp = (void *) skb->data; | 1374 | struct hci_rp_read_rssi *rp = (void *) skb->data; |
@@ -2995,10 +2944,6 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb, | |||
2995 | hci_cc_read_clock(hdev, skb); | 2944 | hci_cc_read_clock(hdev, skb); |
2996 | break; | 2945 | break; |
2997 | 2946 | ||
2998 | case HCI_OP_READ_LOCAL_AMP_ASSOC: | ||
2999 | hci_cc_read_local_amp_assoc(hdev, skb); | ||
3000 | break; | ||
3001 | |||
3002 | case HCI_OP_READ_INQ_RSP_TX_POWER: | 2947 | case HCI_OP_READ_INQ_RSP_TX_POWER: |
3003 | hci_cc_read_inq_rsp_tx_power(hdev, skb); | 2948 | hci_cc_read_inq_rsp_tx_power(hdev, skb); |
3004 | break; | 2949 | break; |
@@ -3103,10 +3048,6 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb, | |||
3103 | hci_cc_set_adv_param(hdev, skb); | 3048 | hci_cc_set_adv_param(hdev, skb); |
3104 | break; | 3049 | break; |
3105 | 3050 | ||
3106 | case HCI_OP_WRITE_REMOTE_AMP_ASSOC: | ||
3107 | hci_cc_write_remote_amp_assoc(hdev, skb); | ||
3108 | break; | ||
3109 | |||
3110 | case HCI_OP_READ_RSSI: | 3051 | case HCI_OP_READ_RSSI: |
3111 | hci_cc_read_rssi(hdev, skb); | 3052 | hci_cc_read_rssi(hdev, skb); |
3112 | break; | 3053 | break; |