From: Srinu Jella Date: Wed, 30 Nov 2016 09:55:12 +0000 (+0530) Subject: Synchronize hl data operations X-Git-Tag: android-x86-8.1-r1~196^2~19^2~42^2~54^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=4db816d09346c81a6504f53ed05a5dfe8b727372;p=android-x86%2Fsystem-bt.git Synchronize hl data operations Use Case: BT crash seen while transferring data using HDP APP to remote health device. Steps: 1. Pair with HDP device 2. Run HDP APP and transfer data to Remote HDP device. Failure: BT automatically resets and recovers. Root Cause: Synchronize BITF HL free buffer as simultaneously free buffer from BTIF and BTU thread lead to sigabort. Fix: Validate Tx packet before memcpy as it can be free from different thread. Test: mm -j8 Change-Id: I566f62ce02c8e95c9f4b8d7155132e4434657f66 --- diff --git a/bta/hl/bta_hl_act.cc b/bta/hl/bta_hl_act.cc index 0a8e8d05d..569f66c0c 100644 --- a/bta/hl/bta_hl_act.cc +++ b/bta/hl/bta_hl_act.cc @@ -372,6 +372,11 @@ void bta_hl_dch_ci_get_tx_data(uint8_t app_idx, uint8_t mcl_idx, APPL_TRACE_DEBUG("bta_hl_dch_ci_get_tx_data"); #endif + if (p_data != NULL) { + status = p_data->ci_get_put_data.status; + APPL_TRACE_WARNING("%s: status=%d", __func__, status); + } + p_dcb->cout_oper &= ~BTA_HL_CO_GET_TX_DATA_MASK; if (p_dcb->close_pending) { @@ -381,6 +386,8 @@ void bta_hl_dch_ci_get_tx_data(uint8_t app_idx, uint8_t mcl_idx, if (!p_dcb->cout_oper) { close_dch = true; } + } else if (status == BTA_HL_STATUS_FAIL) { + free_buf = TRUE; } else { result = MCA_WriteReq((tMCA_DL)p_dcb->mdl_handle, p_dcb->p_tx_pkt); if (result != MCA_SUCCESS) { diff --git a/btif/co/bta_hl_co.cc b/btif/co/bta_hl_co.cc index 66699daea..a4ddbb6a9 100644 --- a/btif/co/bta_hl_co.cc +++ b/btif/co/bta_hl_co.cc @@ -302,7 +302,7 @@ void bta_hl_co_get_tx_data(uint8_t app_id, tBTA_HL_MDL_HANDLE mdl_handle, &mdl_idx)) { p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); - if (p_dcb->tx_size <= buf_size) { + if ((p_dcb->tx_size <= buf_size) && p_dcb->p_tx_pkt) { memcpy(p_buf, p_dcb->p_tx_pkt, p_dcb->tx_size); osi_free_and_reset((void**)&p_dcb->p_tx_pkt); p_dcb->tx_size = 0;