summaryrefslogtreecommitdiffstats
path: root/bta/hl/bta_hl_act.c
diff options
context:
space:
mode:
Diffstat (limited to 'bta/hl/bta_hl_act.c')
-rw-r--r--bta/hl/bta_hl_act.c2807
1 files changed, 2807 insertions, 0 deletions
diff --git a/bta/hl/bta_hl_act.c b/bta/hl/bta_hl_act.c
new file mode 100644
index 0000000..0f46e5e
--- /dev/null
+++ b/bta/hl/bta_hl_act.c
@@ -0,0 +1,2807 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2003-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * This file contains the HeaLth device profile (HL) action functions for
+ * the state machine.
+ *
+ ******************************************************************************/
+
+#include <string.h>
+
+#include "bt_target.h"
+#if defined(HL_INCLUDED) && (HL_INCLUDED == TRUE)
+
+#include "gki.h"
+#include "sdp_api.h"
+#include "bta_sys.h"
+#include "port_api.h"
+#include "sdp_api.h"
+#include "bta_hl_api.h"
+#include "bta_hl_int.h"
+#include "utl.h"
+#include "bd.h"
+#include "mca_defs.h"
+#include "mca_api.h"
+
+/*****************************************************************************
+** Local Function prototypes
+*****************************************************************************/
+#if (BTA_HL_DEBUG == TRUE && BT_TRACE_VERBOSE == TRUE)
+static char *bta_hl_mcap_evt_code(UINT8 evt_code);
+static char *bta_hl_dch_oper_code(tBTA_HL_DCH_OPER oper_code);
+static char *bta_hl_cback_evt_code(UINT8 evt_code);
+#endif
+static void bta_hl_sdp_cback(UINT8 sdp_op, UINT8 app_idx, UINT8 mcl_idx,
+ UINT8 mdl_idx, UINT16 status);
+static void bta_hl_sdp_cback0(UINT16 status);
+static void bta_hl_sdp_cback1(UINT16 status);
+static void bta_hl_sdp_cback2(UINT16 status);
+static void bta_hl_sdp_cback3(UINT16 status);
+static void bta_hl_sdp_cback4(UINT16 status);
+static void bta_hl_sdp_cback5(UINT16 status);
+static void bta_hl_sdp_cback6(UINT16 status);
+
+
+static tSDP_DISC_CMPL_CB * const bta_hl_sdp_cback_arr[] = {
+ bta_hl_sdp_cback0,
+ bta_hl_sdp_cback1,
+ bta_hl_sdp_cback2,
+ bta_hl_sdp_cback3,
+ bta_hl_sdp_cback4,
+ bta_hl_sdp_cback5,
+ bta_hl_sdp_cback6
+};
+
+
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_mca_cong_change
+**
+** Description Action routine for processing congestion change notification
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_mca_cong_change(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tMCA_CONG_CHG *p_cong_chg = &p_data->mca_evt.mca_data.cong_chg;
+ tBTA_HL evt_data;
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG2("bta_hl_dch_mca_cong_change mdl_id=%d cong=%d",
+ p_cong_chg->mdl_id,
+ p_cong_chg->cong);
+#endif
+ evt_data.dch_cong_ind.cong =
+ p_dcb->cong = p_cong_chg->cong;
+ evt_data.dch_cong_ind.mdl_handle = p_dcb->mdl_handle;
+ evt_data.dch_cong_ind.mcl_handle = p_mcb->mcl_handle;
+ evt_data.dch_cong_ind.app_handle = p_acb->app_handle;
+
+ p_acb->p_cback(BTA_HL_CONG_CHG_IND_EVT ,(tBTA_HL *) &evt_data );
+}
+
+
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_echo_test
+**
+** Description Action routine for processing echo test request
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_echo_test(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_echo_test");
+#endif
+
+ p_dcb->echo_oper = BTA_HL_ECHO_OP_CI_GET_ECHO_DATA;
+ p_dcb->cout_oper |= BTA_HL_CO_GET_ECHO_DATA_MASK;
+
+ bta_hl_co_get_echo_data(p_acb->app_id, p_mcb->mcl_handle,
+ p_dcb->p_echo_tx_pkt->len,
+ BTA_HL_GET_BUF_PTR(p_dcb->p_echo_tx_pkt),
+ BTA_HL_CI_GET_ECHO_DATA_EVT);
+
+}
+/*******************************************************************************
+**
+** Function bta_hl_dch_sdp_init
+**
+** Description Action routine for processing DCH SDP initiation
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_sdp_init(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_sdp_init");
+#endif
+ if ( p_mcb->sdp_oper == BTA_HL_SDP_OP_NONE)
+ {
+ p_mcb->sdp_mdl_idx = mdl_idx;
+ if (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_OPEN )
+ {
+ p_mcb->sdp_oper = BTA_HL_SDP_OP_DCH_OPEN_INIT;
+
+ }
+ else
+ {
+ p_mcb->sdp_oper = BTA_HL_SDP_OP_DCH_RECONNECT_INIT;
+ }
+
+ if (bta_hl_init_sdp(p_mcb->sdp_oper, app_idx, mcl_idx, mdl_idx) != BTA_HL_STATUS_OK)
+ {
+ APPL_TRACE_ERROR0("SDP INIT failed");
+ p_mcb->sdp_oper = BTA_HL_SDP_OP_NONE;
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_SDP_FAIL_EVT, p_data);
+ }
+ }
+ else
+ {
+ APPL_TRACE_ERROR0("SDP in use");
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_SDP_FAIL_EVT, p_data);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_close_echo_test
+**
+** Description Action routine for processing the closing of echo test
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_close_echo_test(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_close_echo_test");
+#endif
+
+ switch (p_dcb->echo_oper)
+ {
+ case BTA_HL_ECHO_OP_DCH_CLOSE_CFM:
+ case BTA_HL_ECHO_OP_OPEN_IND:
+ case BTA_HL_ECHO_OP_ECHO_PKT:
+ p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST;
+ break;
+ case BTA_HL_ECHO_OP_MDL_CREATE_CFM:
+ case BTA_HL_ECHO_OP_DCH_OPEN_CFM:
+ case BTA_HL_ECHO_OP_LOOP_BACK:
+ default:
+ break;
+ }
+
+ if (MCA_CloseReq((tMCA_DL) p_dcb->mdl_handle)!= MCA_SUCCESS)
+ {
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_mca_rcv_data
+**
+** Description Action routine for processing the received data
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_mca_rcv_data(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_mca_rcv_data");
+#endif
+
+ if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID)
+ {
+ switch ( p_dcb->echo_oper)
+ {
+ case BTA_HL_ECHO_OP_ECHO_PKT:
+
+ if (MCA_WriteReq((tMCA_DL) p_dcb->mdl_handle, p_data->mca_rcv_data_evt.p_pkt) != MCA_SUCCESS)
+ {
+ utl_freebuf((void **) &p_data->mca_rcv_data_evt.p_pkt);
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_ECHO_TEST_EVT, p_data);
+ }
+ break;
+ case BTA_HL_ECHO_OP_LOOP_BACK:
+
+ p_dcb->p_echo_rx_pkt = p_data->mca_rcv_data_evt.p_pkt;
+ p_dcb->echo_oper = BTA_HL_ECHO_OP_CI_PUT_ECHO_DATA;
+ p_dcb->cout_oper |= BTA_HL_CO_PUT_ECHO_DATA_MASK;
+ p_dcb->ci_put_echo_data_status = BTA_HL_STATUS_FAIL;
+
+ bta_hl_co_put_echo_data(p_acb->app_id, p_mcb->mcl_handle,
+ p_dcb->p_echo_rx_pkt->len,
+ BTA_HL_GET_BUF_PTR(p_dcb->p_echo_rx_pkt),
+ BTA_HL_CI_PUT_ECHO_DATA_EVT);
+ break;
+ default:
+ APPL_TRACE_ERROR1("Unknonw echo_oper=%d",p_dcb->echo_oper);
+ break;
+ }
+
+ }
+ else
+ {
+ p_dcb->cout_oper |= BTA_HL_CO_PUT_RX_DATA_MASK;
+ p_dcb->p_rx_pkt = p_data->mca_rcv_data_evt.p_pkt;
+
+ bta_hl_co_put_rx_data(p_acb->app_id, p_dcb->mdl_handle,
+ p_dcb->p_rx_pkt->len,
+ BTA_HL_GET_BUF_PTR(p_dcb->p_rx_pkt),
+ BTA_HL_CI_PUT_RX_DATA_EVT);
+
+
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_ci_put_echo_data
+**
+** Description Action routine for processing the call-in of the
+** put echo data event
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_ci_put_echo_data(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_ci_put_echo_data");
+#endif
+
+ p_dcb->cout_oper &= ~BTA_HL_CO_PUT_ECHO_DATA_MASK;
+ utl_freebuf((void **) &p_dcb->p_echo_rx_pkt);
+ p_dcb->ci_put_echo_data_status = p_data->ci_get_put_echo_data.status;
+
+ p_dcb->echo_oper = BTA_HL_ECHO_OP_DCH_CLOSE_CFM;
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_ECHO_TEST_EVT, p_data);
+}
+
+
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_ci_get_echo_data
+**
+** Description Action routine for processing the call-in of the
+** get echo data event
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_ci_get_echo_data(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tBTA_HL_STATUS status;
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_ci_get_echo_data");
+#endif
+
+ p_dcb->cout_oper &= ~BTA_HL_CO_GET_ECHO_DATA_MASK;
+
+ if (!p_dcb->abort_oper)
+ {
+ status = p_data->ci_get_put_echo_data.status;
+ if (status == BTA_HL_STATUS_OK)
+ {
+ p_dcb->echo_oper = BTA_HL_ECHO_OP_MDL_CREATE_CFM;
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_OPEN_EVT, p_data);
+ }
+ else
+ {
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+ }
+ else
+ {
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_ci_put_rx_data
+**
+** Description Action routine for processing the call-in of the
+** put rx data event
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_ci_put_rx_data(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tBTA_HL evt_data;
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_ci_put_rx_data");
+#endif
+
+ p_dcb->cout_oper &= ~BTA_HL_CO_PUT_RX_DATA_MASK;
+ utl_freebuf((void **) &p_dcb->p_rx_pkt);
+ bta_hl_build_rcv_data_ind(&evt_data,
+ p_acb->app_handle,
+ p_mcb->mcl_handle,
+ p_dcb->mdl_handle);
+ p_acb->p_cback(BTA_HL_DCH_RCV_DATA_IND_EVT,(tBTA_HL *) &evt_data );
+ if (p_dcb->close_pending)
+ {
+ if (!p_dcb->cout_oper)
+ {
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_EVT, p_data);
+ }
+
+ }
+}
+
+
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_ci_get_tx_data
+**
+** Description Action routine for processing the call-in of the
+** get tx data event
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_ci_get_tx_data(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tMCA_RESULT result;
+ tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
+ BOOLEAN free_buf = FALSE;
+ BOOLEAN close_dch = FALSE;
+ tBTA_HL evt_data;
+
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_ci_get_tx_data");
+#endif
+
+ p_dcb->cout_oper &= ~BTA_HL_CO_GET_TX_DATA_MASK;
+
+ if (p_dcb->close_pending)
+ {
+ status = BTA_HL_STATUS_FAIL;
+ free_buf = TRUE;
+
+ if (!p_dcb->cout_oper)
+ {
+ close_dch = TRUE;
+ }
+ }
+ else
+ {
+ if ((result = MCA_WriteReq((tMCA_DL) p_dcb->mdl_handle, p_dcb->p_tx_pkt)) != MCA_SUCCESS)
+ {
+ if (result == MCA_BUSY)
+ {
+ status = BTA_HL_STATUS_DCH_BUSY;
+ }
+ else
+ {
+ status = BTA_HL_STATUS_FAIL;
+ }
+ free_buf = TRUE;
+ }
+ else
+ {
+ p_dcb->p_tx_pkt = NULL;
+ }
+ }
+
+ if (free_buf)
+ {
+ utl_freebuf((void **) &p_dcb->p_tx_pkt);
+ }
+
+ bta_hl_build_send_data_cfm(&evt_data,
+ p_acb->app_handle,
+ p_mcb->mcl_handle,
+ p_dcb->mdl_handle,
+ status);
+ p_acb->p_cback(BTA_HL_DCH_SEND_DATA_CFM_EVT,(tBTA_HL *) &evt_data );
+
+ if (close_dch)
+ {
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_EVT, p_data);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_send_data
+**
+** Description Action routine for processing api send data request
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_send_data(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tBTA_HL evt_data;
+ BOOLEAN success = TRUE;
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_send_data");
+#endif
+
+ if (!(p_dcb->cout_oper & BTA_HL_CO_GET_TX_DATA_MASK))
+ {
+ if ((p_dcb->p_tx_pkt = bta_hl_get_buf(p_data->api_send_data.pkt_size)) != NULL)
+ {
+ bta_hl_co_get_tx_data( p_acb->app_id,
+ p_dcb->mdl_handle,
+ p_data->api_send_data.pkt_size,
+ BTA_HL_GET_BUF_PTR(p_dcb->p_tx_pkt),
+ BTA_HL_CI_GET_TX_DATA_EVT);
+ p_dcb->cout_oper |= BTA_HL_CO_GET_TX_DATA_MASK;
+ }
+ else
+ {
+ success = FALSE;
+ }
+ }
+ else
+ {
+ success = FALSE;
+ }
+
+ if (!success)
+ {
+ bta_hl_build_send_data_cfm(&evt_data,
+ p_acb->app_handle,
+ p_mcb->mcl_handle,
+ p_dcb->mdl_handle,
+ BTA_HL_STATUS_FAIL);
+ p_acb->p_cback(BTA_HL_DCH_SEND_DATA_CFM_EVT,(tBTA_HL *) &evt_data );
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_close_cmpl
+**
+** Description Action routine for processing the close complete event
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_close_cmpl(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tBTA_HL evt_data;
+ tBTA_HL_EVT event;
+ BOOLEAN send_evt=TRUE;
+ tBTA_HL_STATUS status;
+
+#if (BTA_HL_DEBUG == TRUE)
+#if (BT_TRACE_VERBOSE == TRUE)
+ APPL_TRACE_DEBUG1("bta_hl_dch_close_cmpl dch oper=%s", bta_hl_dch_oper_code(p_dcb->dch_oper));
+#else
+ APPL_TRACE_DEBUG1("bta_hl_dch_close_cmpl dch oper=%d", p_dcb->dch_oper);
+#endif
+#endif
+
+ switch (p_dcb->dch_oper)
+ {
+ case BTA_HL_DCH_OP_LOCAL_OPEN:
+ case BTA_HL_DCH_OP_LOCAL_RECONNECT:
+
+ if (p_dcb->abort_oper & BTA_HL_ABORT_LOCAL_MASK)
+ {
+ bta_hl_build_abort_cfm(&evt_data,
+ p_acb->app_handle,
+ p_mcb->mcl_handle,
+ BTA_HL_STATUS_OK);
+ event = BTA_HL_DCH_ABORT_CFM_EVT;
+ }
+ else if (p_dcb->abort_oper & BTA_HL_ABORT_REMOTE_MASK )
+ {
+ bta_hl_build_abort_ind(&evt_data,
+ p_acb->app_handle,
+ p_mcb->mcl_handle);
+ event = BTA_HL_DCH_ABORT_IND_EVT;
+ }
+ else
+ {
+ bta_hl_build_dch_open_cfm(&evt_data,
+ p_acb->app_handle,
+ p_mcb->mcl_handle,
+ BTA_HL_INVALID_MDL_HANDLE,
+ 0,0,0,0,0, BTA_HL_STATUS_FAIL);
+ event = BTA_HL_DCH_OPEN_CFM_EVT;
+ if (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_RECONNECT)
+ {
+ event = BTA_HL_DCH_RECONNECT_CFM_EVT;
+ }
+ }
+ break;
+
+ case BTA_HL_DCH_OP_LOCAL_CLOSE:
+ case BTA_HL_DCH_OP_REMOTE_DELETE:
+ case BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT:
+ case BTA_HL_DCH_OP_NONE:
+
+ bta_hl_build_dch_close_cfm(&evt_data,
+ p_acb->app_handle,
+ p_mcb->mcl_handle,
+ p_dcb->mdl_handle,
+ BTA_HL_STATUS_OK);
+ event = BTA_HL_DCH_CLOSE_CFM_EVT;
+ break;
+
+ case BTA_HL_DCH_OP_REMOTE_CLOSE:
+ bta_hl_build_dch_close_ind(&evt_data,
+ p_acb->app_handle,
+ p_mcb->mcl_handle,
+ p_dcb->mdl_handle,
+ p_dcb->intentional_close);
+ event = BTA_HL_DCH_CLOSE_IND_EVT;
+ break;
+
+ case BTA_HL_DCH_OP_REMOTE_OPEN:
+
+ if (p_dcb->abort_oper & BTA_HL_ABORT_LOCAL_MASK)
+ {
+ bta_hl_build_abort_cfm(&evt_data,
+ p_acb->app_handle,
+ p_mcb->mcl_handle,
+ BTA_HL_STATUS_OK);
+ event = BTA_HL_DCH_ABORT_CFM_EVT;
+ }
+ else if (p_dcb->abort_oper & BTA_HL_ABORT_REMOTE_MASK )
+ {
+ bta_hl_build_abort_ind(&evt_data,
+ p_acb->app_handle,
+ p_mcb->mcl_handle);
+ event = BTA_HL_DCH_ABORT_IND_EVT;
+ }
+ else
+ {
+ bta_hl_build_dch_close_ind(&evt_data,
+ p_acb->app_handle,
+ p_mcb->mcl_handle,
+ p_dcb->mdl_handle,
+ p_dcb->intentional_close);
+ event = BTA_HL_DCH_CLOSE_IND_EVT;
+ }
+ break;
+
+ case BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST:
+ /* this is normal echo test close */
+ case BTA_HL_DCH_OP_REMOTE_CREATE:
+ case BTA_HL_DCH_OP_REMOTE_RECONNECT:
+ send_evt=FALSE;
+ break;
+
+ default:
+#if (BTA_HL_DEBUG == TRUE)
+#if (BT_TRACE_VERBOSE == TRUE)
+ APPL_TRACE_ERROR1("DCH operation not found oper=%s", bta_hl_dch_oper_code(p_dcb->dch_oper));
+#else
+ APPL_TRACE_ERROR1("DCH operation not found oper=%d", p_dcb->dch_oper);
+#endif
+#endif
+ send_evt=FALSE;
+ break;
+ }
+
+ if ( p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID )
+ {
+ p_mcb->echo_test = FALSE;
+ send_evt=FALSE;
+
+ if ( p_dcb->dch_oper != BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST)
+ {
+ switch (p_dcb->echo_oper)
+ {
+ case BTA_HL_ECHO_OP_CI_GET_ECHO_DATA:
+ case BTA_HL_ECHO_OP_SDP_INIT:
+ case BTA_HL_ECHO_OP_MDL_CREATE_CFM:
+ case BTA_HL_ECHO_OP_DCH_OPEN_CFM:
+ case BTA_HL_ECHO_OP_LOOP_BACK:
+
+ status = BTA_HL_STATUS_FAIL;
+ send_evt = TRUE;
+ break;
+ case BTA_HL_ECHO_OP_OPEN_IND:
+ case BTA_HL_ECHO_OP_ECHO_PKT:
+ break;
+ default:
+ APPL_TRACE_ERROR1("Invalid echo_oper=%d", p_dcb->echo_oper);
+ break;
+ }
+ }
+ else
+ {
+ status = p_dcb->ci_put_echo_data_status;
+ send_evt = TRUE;
+ }
+
+ if (send_evt)
+ {
+ bta_hl_build_echo_test_cfm(&evt_data,
+ p_acb->app_handle,
+ p_mcb->mcl_handle,
+ status);
+ event = BTA_HL_DCH_ECHO_TEST_CFM_EVT;
+ }
+ }
+
+ bta_hl_clean_mdl_cb(app_idx, mcl_idx, mdl_idx);
+
+ if (send_evt)
+ {
+ if (p_acb->p_cback)
+ {
+#if (BTA_HL_DEBUG == TRUE)
+#if (BT_TRACE_VERBOSE == TRUE)
+ APPL_TRACE_DEBUG1("Send Event: %s", bta_hl_cback_evt_code(event));
+#else
+ APPL_TRACE_DEBUG1("Send Event: 0x%02x", event);
+#endif
+#endif
+ p_acb->p_cback(event,(tBTA_HL *) &evt_data );
+ }
+ }
+ /* check cch close is in progress or not */
+ bta_hl_check_cch_close(app_idx, mcl_idx, p_data, FALSE);
+}
+/*******************************************************************************
+**
+** Function bta_hl_dch_mca_close_ind
+**
+** Description Action routine for processing the close indication
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_mca_close_ind(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+
+#if (BTA_HL_DEBUG == TRUE)
+#if (BT_TRACE_VERBOSE == TRUE)
+ APPL_TRACE_DEBUG1("bta_hl_dch_mca_close_ind dch oper=%s", bta_hl_dch_oper_code(p_dcb->dch_oper));
+#else
+ APPL_TRACE_DEBUG1("bta_hl_dch_mca_close_ind dch oper=%d", p_dcb->dch_oper);
+#endif
+#endif
+
+ p_dcb->intentional_close = FALSE;
+ if (p_data->mca_evt.mca_data.close_ind.reason == L2CAP_DISC_OK)
+ {
+ p_dcb->intentional_close = TRUE;
+ }
+
+ if (!p_dcb->cout_oper)
+ {
+ if ((p_dcb->dch_oper != BTA_HL_DCH_OP_REMOTE_OPEN) &&
+ (p_dcb->dch_oper != BTA_HL_DCH_OP_REMOTE_RECONNECT))
+ {
+ p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_CLOSE;
+ }
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+ else
+ {
+ p_dcb->close_pending = TRUE;
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_mca_close_cfm
+**
+** Description Action routine for processing the close confirmation
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_mca_close_cfm(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+
+
+#if (BTA_HL_DEBUG == TRUE)
+#if (BT_TRACE_VERBOSE == TRUE)
+ APPL_TRACE_DEBUG1("bta_hl_dch_mca_close_cfm dch_oper=%s", bta_hl_dch_oper_code(p_dcb->dch_oper) );
+#else
+ APPL_TRACE_DEBUG1("bta_hl_dch_mca_close_cfm dch_oper=%d", p_dcb->dch_oper);
+#endif
+#endif
+
+ switch (p_dcb->dch_oper)
+ {
+ case BTA_HL_DCH_OP_LOCAL_CLOSE:
+ case BTA_HL_DCH_OP_LOCAL_OPEN:
+ case BTA_HL_DCH_OP_LOCAL_RECONNECT:
+ case BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST:
+ case BTA_HL_DCH_OP_REMOTE_DELETE:
+ case BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT:
+ case BTA_HL_DCH_OP_NONE:
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ break;
+ default:
+#if (BTA_HL_DEBUG == TRUE)
+#if (BT_TRACE_VERBOSE == TRUE)
+ APPL_TRACE_ERROR1("Invalid dch_oper=%s for close cfm", bta_hl_dch_oper_code(p_dcb->dch_oper) );
+#else
+ APPL_TRACE_ERROR1("Invalid dch_oper=%d for close cfm", p_dcb->dch_oper);
+#endif
+#endif
+ break;
+ }
+
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_mca_close
+**
+** Description Action routine for processing the DCH close request
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_mca_close(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
+ tBTA_HL evt_data;
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_mca_close");
+#endif
+ if (!p_dcb->cout_oper)
+ {
+ p_dcb->close_pending = FALSE;
+ if (MCA_CloseReq((tMCA_DL)p_dcb->mdl_handle)== MCA_SUCCESS)
+ {
+ p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_CLOSE;
+ }
+ else
+ {
+ status = BTA_HL_STATUS_FAIL;
+ }
+
+ if ((status != BTA_HL_STATUS_OK) &&
+ (p_mcb->cch_close_dch_oper != BTA_HL_CCH_CLOSE_OP_DCH_CLOSE))
+ {
+ bta_hl_build_dch_close_cfm(&evt_data,
+ p_acb->app_handle,
+ p_mcb->mcl_handle,
+ p_data->api_dch_close.mdl_handle,
+ status);
+ p_acb->p_cback(BTA_HL_DCH_CLOSE_CFM_EVT,(tBTA_HL *) &evt_data );
+ }
+ }
+ else
+ {
+ p_dcb->close_pending = TRUE;
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_mca_open_ind
+**
+** Description Action routine for processing the open indication
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_mca_open_ind(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tMCA_DL_OPEN *p_open_ind = &p_data->mca_evt.mca_data.open_ind;
+ tBTA_HL evt_data;
+ tBTA_HL_EVT event;
+ UINT8 old_dch_oper;
+ BOOLEAN send_event = FALSE;
+
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_mca_open_ind");
+#endif
+ if ((p_dcb->dch_oper == BTA_HL_DCH_OP_REMOTE_OPEN) ||
+ (p_dcb->dch_oper == BTA_HL_DCH_OP_REMOTE_RECONNECT) )
+ {
+ p_dcb->mdl_handle = (tBTA_HL_MDL_HANDLE) p_open_ind->mdl;
+ p_dcb->mtu = p_open_ind->mtu;
+
+ evt_data.dch_open_ind.mdl_handle = p_dcb->mdl_handle;
+ evt_data.dch_open_ind.mcl_handle = p_mcb->mcl_handle;
+ evt_data.dch_open_ind.app_handle = p_acb->app_handle;
+
+ evt_data.dch_open_ind.local_mdep_id = p_dcb->local_mdep_id;
+ evt_data.dch_open_ind.mdl_id = p_dcb->mdl_id;
+ evt_data.dch_open_ind.mtu = p_dcb->mtu;
+
+ if ( p_dcb->chnl_cfg.fcr_opt.mode == L2CAP_FCR_ERTM_MODE )
+ {
+ evt_data.dch_open_ind.dch_mode = BTA_HL_DCH_MODE_RELIABLE;
+ if (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx))
+ {
+ p_dcb->is_the_first_reliable = TRUE;
+ }
+ }
+ else
+ {
+ evt_data.dch_open_ind.dch_mode = BTA_HL_DCH_MODE_STREAMING;
+ }
+ evt_data.dch_open_ind.first_reliable = p_dcb->is_the_first_reliable ;
+
+ old_dch_oper = p_dcb->dch_oper;
+ p_dcb->dch_oper = BTA_HL_DCH_OP_NONE;
+
+
+ }
+
+ switch (old_dch_oper)
+ {
+ case BTA_HL_DCH_OP_REMOTE_OPEN:
+
+ p_dcb->dch_mode = evt_data.dch_open_ind.dch_mode;
+ if (p_dcb->local_mdep_id != BTA_HL_ECHO_TEST_MDEP_ID)
+ {
+ bta_hl_save_mdl_cfg(app_idx, mcl_idx,mdl_idx);
+ event= BTA_HL_DCH_OPEN_IND_EVT;
+ send_event= TRUE;
+ }
+ else
+ {
+ p_dcb->echo_oper = BTA_HL_ECHO_OP_ECHO_PKT;
+ }
+
+ break;
+
+ case BTA_HL_DCH_OP_REMOTE_RECONNECT:
+
+ if (bta_hl_validate_chan_cfg(app_idx, mcl_idx, mdl_idx))
+ {
+ bta_hl_save_mdl_cfg(app_idx, mcl_idx,mdl_idx);
+ event= BTA_HL_DCH_RECONNECT_IND_EVT;
+ send_event= TRUE;
+ }
+ else
+ {
+ if (MCA_CloseReq((tMCA_DL) p_dcb->mdl_handle) == MCA_SUCCESS)
+ {
+ p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT;
+ }
+ else
+ {
+ APPL_TRACE_ERROR0("Unabel to close DCH for reconnect cfg mismatch");
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (send_event)
+ {
+ p_acb->p_cback(event ,(tBTA_HL *) &evt_data );
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_mca_open_cfm
+**
+** Description Action routine for processing the open confirmation
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_mca_open_cfm(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tMCA_DL_OPEN *p_open_cfm = &p_data->mca_evt.mca_data.open_cfm;
+ tBTA_HL evt_data;
+ tBTA_HL_EVT event;
+ UINT8 old_dch_oper;
+ tBTA_HL_DCH_MODE dch_mode;
+ BOOLEAN send_event = FALSE;
+
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_mca_open_cfm");
+#endif
+ if ((p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_OPEN) ||
+ (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_RECONNECT))
+ {
+ p_dcb->mdl_handle = (tBTA_HL_MDL_HANDLE) p_open_cfm->mdl;
+ p_dcb->mtu = p_open_cfm->mtu;
+
+ /*todo verify dch_mode, mtu and fcs for reconnect */
+ if ( p_dcb->chnl_cfg.fcr_opt.mode == L2CAP_FCR_ERTM_MODE )
+ {
+ dch_mode = BTA_HL_DCH_MODE_RELIABLE;
+ }
+ else
+ {
+ dch_mode = BTA_HL_DCH_MODE_STREAMING;
+ }
+
+ if (p_dcb->local_mdep_id != BTA_HL_ECHO_TEST_MDEP_ID)
+ {
+ if (dch_mode == BTA_HL_DCH_MODE_RELIABLE )
+ {
+ if (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx))
+ {
+ p_dcb->is_the_first_reliable = TRUE;
+ }
+ }
+ }
+
+ bta_hl_build_dch_open_cfm(&evt_data, p_acb->app_handle,
+ p_mcb->mcl_handle,
+ p_dcb->mdl_handle,
+ p_dcb->local_mdep_id,
+ p_dcb->mdl_id, dch_mode,
+ p_dcb->is_the_first_reliable,
+ p_dcb->mtu,
+ BTA_HL_STATUS_OK);
+
+ old_dch_oper = p_dcb->dch_oper;
+ p_dcb->dch_oper = BTA_HL_DCH_OP_NONE;
+ }
+
+ switch (old_dch_oper)
+ {
+ case BTA_HL_DCH_OP_LOCAL_OPEN:
+
+ p_dcb->dch_mode = dch_mode;
+ if (p_dcb->local_mdep_id != BTA_HL_ECHO_TEST_MDEP_ID)
+ {
+ bta_hl_save_mdl_cfg(app_idx, mcl_idx, mdl_idx);
+ event= BTA_HL_DCH_OPEN_CFM_EVT;
+ send_event= TRUE;
+ }
+ else
+ {
+ p_dcb->echo_oper = BTA_HL_ECHO_OP_LOOP_BACK;
+ if (MCA_WriteReq((tMCA_DL) p_dcb->mdl_handle, p_dcb->p_echo_tx_pkt)!= MCA_SUCCESS)
+ {
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_ECHO_TEST_EVT, p_data);
+ }
+ else
+ {
+ p_dcb->p_echo_tx_pkt = NULL;
+ }
+ }
+ break;
+
+ case BTA_HL_DCH_OP_LOCAL_RECONNECT:
+
+ if (bta_hl_validate_chan_cfg(app_idx, mcl_idx, mdl_idx))
+ {
+ bta_hl_save_mdl_cfg(app_idx, mcl_idx,mdl_idx);
+ event= BTA_HL_DCH_RECONNECT_CFM_EVT;
+ send_event= TRUE;
+ }
+ else
+ {
+ if (MCA_CloseReq((tMCA_DL) p_dcb->mdl_handle) == MCA_SUCCESS)
+ {
+ p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT;
+ }
+ else
+ {
+ APPL_TRACE_ERROR0("Unabel to close DCH for reconnect cfg mismatch");
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (send_event)
+ p_acb->p_cback(event ,(tBTA_HL *) &evt_data );
+}
+
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_mca_abort_ind
+**
+** Description Action routine for processing the abort indication
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_mca_abort_ind(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_mca_abort_ind");
+#endif
+
+ p_dcb->abort_oper |= BTA_HL_ABORT_REMOTE_MASK;
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_mca_abort_cfm
+**
+** Description Action routine for processing the abort confirmation
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_mca_abort_cfm(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tBTA_HL evt_data;
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_mca_abort_cfm");
+#endif
+
+ if (p_dcb->abort_oper)
+ {
+ if (p_data->mca_evt.mca_data.abort_cfm.rsp_code != MCA_RSP_SUCCESS )
+ {
+ if (p_dcb->abort_oper & BTA_HL_ABORT_LOCAL_MASK)
+ {
+ bta_hl_build_abort_cfm(&evt_data,
+ p_acb->app_handle,
+ p_mcb->mcl_handle,
+ BTA_HL_STATUS_FAIL);
+ p_acb->p_cback(BTA_HL_DCH_ABORT_CFM_EVT ,(tBTA_HL *) &evt_data );
+ }
+ }
+ else
+ {
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+ }
+ else
+ {
+ APPL_TRACE_ERROR0("Not expecting Abort CFM ");
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_mca_abort
+**
+** Description Action routine for processing the abort request
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_mca_abort(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tMCA_RESULT mca_result;
+ tBTA_HL evt_data;
+
+ if (((p_mcb->sdp_oper == BTA_HL_SDP_OP_DCH_OPEN_INIT) ||
+ (p_mcb->sdp_oper == BTA_HL_SDP_OP_DCH_RECONNECT_INIT)) &&
+ (p_mcb->sdp_mdl_idx == mdl_idx) )
+ {
+ p_dcb->abort_oper |= BTA_HL_ABORT_PENDING_MASK;
+ return;
+ }
+ else if (p_dcb->echo_oper == BTA_HL_ECHO_OP_CI_GET_ECHO_DATA)
+ {
+ p_dcb->abort_oper |= BTA_HL_ABORT_PENDING_MASK;
+ return;
+ }
+
+ p_dcb->abort_oper &= ~BTA_HL_ABORT_PENDING_MASK;
+
+ if ((mca_result = MCA_Abort((tMCA_CL) p_mcb->mcl_handle))!= MCA_SUCCESS)
+ {
+ if (mca_result == MCA_NO_RESOURCES)
+ {
+ p_dcb->abort_oper |= BTA_HL_ABORT_PENDING_MASK;
+ }
+ else
+ {
+ if (p_dcb->abort_oper & BTA_HL_ABORT_LOCAL_MASK)
+ {
+ bta_hl_build_abort_cfm(&evt_data,
+ p_acb->app_handle,
+ p_mcb->mcl_handle,
+ BTA_HL_STATUS_FAIL);
+ p_acb->p_cback(BTA_HL_DCH_ABORT_CFM_EVT ,(tBTA_HL *) &evt_data );
+ }
+ bta_hl_check_cch_close(app_idx, mcl_idx, p_data, FALSE);
+ }
+
+
+ }
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG1("bta_hl_dch_mca_abort abort_oper=0x%x", p_dcb->abort_oper);
+#endif
+
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_mca_reconnect_ind
+**
+** Description Action routine for processing the reconnect indication
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_mca_reconnect_ind(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tBTA_HL_MDL_CFG *p_mdl_cfg;
+ tMCA_EVT_HDR *p_reconnect_ind = &p_data->mca_evt.mca_data.reconnect_ind;
+ UINT8 mdl_cfg_idx, in_use_mdl_idx, mdep_cfg_idx;
+ UINT8 rsp_code = MCA_RSP_SUCCESS;
+
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG1("bta_hl_dch_mca_reconnect_ind mdl_id=%d", p_reconnect_ind->mdl_id);
+#endif
+
+ if (bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, p_reconnect_ind->mdl_id, &mdl_cfg_idx))
+ {
+ if (!bta_hl_find_mdl_idx(app_idx,mcl_idx,p_reconnect_ind->mdl_id, &in_use_mdl_idx) )
+ {
+ p_mdl_cfg = BTA_HL_GET_MDL_CFG_PTR(app_idx, mdl_cfg_idx);
+
+ if (bta_hl_find_mdep_cfg_idx(app_idx, p_mdl_cfg->local_mdep_id, &mdep_cfg_idx))
+ {
+ p_dcb->in_use = TRUE;
+ p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_RECONNECT;
+ p_dcb->sec_mask = (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
+ p_dcb->peer_mdep_id = 0xFF;
+ p_dcb->local_mdep_id = p_mdl_cfg->local_mdep_id ;
+ p_dcb->local_mdep_cfg_idx = mdep_cfg_idx;
+ p_dcb->local_cfg = BTA_HL_DCH_CFG_UNKNOWN;
+ p_dcb->mdl_id = p_reconnect_ind->mdl_id;
+ p_dcb->mdl_cfg_idx_included = TRUE;
+ p_dcb->mdl_cfg_idx = mdl_cfg_idx;
+ p_dcb->dch_mode = p_mdl_cfg->dch_mode;
+ bta_hl_find_rxtx_apdu_size(app_idx, mdep_cfg_idx,
+ &p_dcb->max_rx_apdu_size,
+ &p_dcb->max_tx_apdu_size);
+ bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data);
+ }
+ else
+ {
+ rsp_code = MCA_RSP_BAD_MDL;
+ }
+ }
+ else
+ {
+ rsp_code = MCA_RSP_BAD_MDL;
+ }
+ }
+ else
+ {
+ rsp_code = MCA_RSP_BAD_MDL;
+ }
+
+ if (MCA_ReconnectMdlRsp((tMCA_CL) p_mcb->mcl_handle,
+ p_dcb->local_mdep_id,
+ p_dcb->mdl_id,
+ rsp_code,
+ &p_dcb->chnl_cfg)!= MCA_SUCCESS)
+ {
+ MCA_Abort((tMCA_CL) p_mcb->mcl_handle);
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_mca_reconnect_cfm
+**
+** Description Action routine for processing the reconenct confirmation
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_mca_reconnect_cfm(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tMCA_RSP_EVT *p_reconnect_cfm = &p_data->mca_evt.mca_data.reconnect_cfm;
+
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_mca_reconnect_cfm");
+#endif
+ if (p_dcb->abort_oper & BTA_HL_ABORT_PENDING_MASK)
+ {
+ p_dcb->abort_oper &= ~BTA_HL_ABORT_PENDING_MASK;
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_ABORT_EVT, p_data);
+ return;
+ }
+
+
+ if (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_RECONNECT)
+ {
+ if (p_reconnect_cfm->rsp_code == MCA_RSP_SUCCESS)
+ {
+
+ bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data);
+
+ if (MCA_DataChnlCfg((tMCA_CL) p_mcb->mcl_handle, &p_dcb->chnl_cfg)!= MCA_SUCCESS)
+ {
+ /* should be able to abort so no checking of the return code */
+ MCA_Abort((tMCA_CL) p_mcb->mcl_handle);
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+ }
+ else
+ {
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_mca_reconnect
+**
+** Description Action routine for processing the reconnect request
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_mca_reconnect(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tMCA_CHNL_CFG *p_chnl_cfg=NULL;
+ UINT8 sdp_idx;
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_mca_reconnect");
+#endif
+ if (bta_hl_find_sdp_idx_using_ctrl_psm(&p_mcb->sdp, p_mcb->ctrl_psm, &sdp_idx))
+ {
+ p_mcb->data_psm = p_mcb->sdp.sdp_rec[sdp_idx].data_psm;
+ if ( MCA_ReconnectMdl((tMCA_CL) p_mcb->mcl_handle,
+ p_dcb->local_mdep_id,
+ p_mcb->data_psm,
+ p_dcb->mdl_id,
+ p_chnl_cfg ) != MCA_SUCCESS)
+ {
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+ }
+ else
+ {
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_create_rsp
+**
+** Description Action routine for processing BTA_HL_API_DCH_CREATE_RSP_EVT
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_create_rsp(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tBTA_HL_API_DCH_CREATE_RSP *p_create_rsp = &p_data->api_dch_create_rsp;
+ UINT8 mca_rsp_code = MCA_RSP_SUCCESS;
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_create_rsp");
+#endif
+ if (p_create_rsp->rsp_code == BTA_HL_DCH_CREATE_RSP_SUCCESS)
+ {
+ p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_OPEN;
+ p_dcb->local_cfg = p_create_rsp->cfg_rsp;
+
+
+
+ bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data);
+ }
+ else
+ {
+ mca_rsp_code = MCA_RSP_CFG_REJ;
+ }
+
+ if (MCA_CreateMdlRsp((tMCA_CL) p_mcb->mcl_handle,
+ p_dcb->local_mdep_id,
+ p_dcb->mdl_id,
+ p_dcb->local_cfg,
+ mca_rsp_code,
+ &p_dcb->chnl_cfg)!= MCA_SUCCESS)
+ {
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_mca_create_ind
+**
+** Description Action routine for processing
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_mca_create_ind(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tMCA_CREATE_IND *p_create_ind = &p_data->mca_evt.mca_data.create_ind;
+ UINT8 mdep_cfg_idx;
+ UINT8 cfg_rsp;
+ UINT8 rsp_code = MCA_RSP_SUCCESS;
+ BOOLEAN send_create_ind_evt = FALSE;
+ tBTA_HL evt_data;
+ tBTA_HL_ECHO_CFG *p_echo_cfg;
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_mca_create_ind");
+#endif
+
+ if (bta_hl_find_mdep_cfg_idx(app_idx, p_create_ind->dep_id, &mdep_cfg_idx))
+ {
+ if (p_create_ind->dep_id == BTA_HL_ECHO_TEST_MDEP_ID )
+ {
+ if (bta_hl_find_echo_cfg_rsp(app_idx, mcl_idx, mdep_cfg_idx,p_create_ind->cfg, &cfg_rsp ))
+ {
+ p_dcb->in_use = TRUE;
+ p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_OPEN;
+ p_dcb->local_mdep_id = p_create_ind->dep_id ;
+ p_dcb->local_mdep_cfg_idx = mdep_cfg_idx;
+ p_dcb->local_cfg = cfg_rsp;
+ p_dcb->remote_cfg = p_create_ind->cfg ;
+ p_dcb->mdl_id = p_create_ind->mdl_id;
+ p_dcb->mdl_cfg_idx_included = FALSE;
+ p_echo_cfg = BTA_HL_GET_ECHO_CFG_PTR(app_idx);
+ p_dcb->max_rx_apdu_size = p_echo_cfg->max_rx_apdu_size;
+ p_dcb->max_tx_apdu_size = p_echo_cfg->max_tx_apdu_size;
+
+ bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data);
+ }
+ else
+ {
+ rsp_code = MCA_RSP_CFG_REJ;
+ }
+ }
+ else
+
+ {
+ p_dcb->in_use = TRUE;
+ p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_CREATE;
+ p_dcb->local_mdep_id = p_create_ind->dep_id ;
+ p_dcb->local_mdep_cfg_idx = mdep_cfg_idx;
+ p_dcb->local_cfg = BTA_HL_DCH_CFG_UNKNOWN;
+ p_dcb->remote_cfg = p_create_ind->cfg;
+ p_dcb->mdl_id = p_create_ind->mdl_id;
+ p_dcb->mdl_cfg_idx_included = FALSE;
+ bta_hl_find_rxtx_apdu_size(app_idx, mdep_cfg_idx,
+ &p_dcb->max_rx_apdu_size,
+ &p_dcb->max_tx_apdu_size);
+ send_create_ind_evt = TRUE;
+ }
+ }
+ else
+ {
+ rsp_code = MCA_RSP_BAD_MDEP;
+ }
+
+ if (send_create_ind_evt)
+ {
+ evt_data.dch_create_ind.mcl_handle = p_mcb->mcl_handle;
+ evt_data.dch_create_ind.app_handle = p_acb->app_handle;
+ evt_data.dch_create_ind.local_mdep_id = p_dcb->local_mdep_id;
+ evt_data.dch_create_ind.mdl_id = p_dcb->mdl_id;
+ evt_data.dch_create_ind.cfg = p_dcb->remote_cfg;
+ p_acb->p_cback(BTA_HL_DCH_CREATE_IND_EVT,(tBTA_HL *) &evt_data );
+ }
+ else
+ {
+ if (MCA_CreateMdlRsp((tMCA_CL) p_mcb->mcl_handle,
+ p_dcb->local_mdep_id,
+ p_dcb->mdl_id,
+ p_dcb->local_cfg,
+ rsp_code,
+ &p_dcb->chnl_cfg)!= MCA_SUCCESS)
+ {
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+ else
+ {
+ if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID)
+ {
+ p_mcb->echo_test = TRUE;
+ p_dcb->echo_oper = BTA_HL_ECHO_OP_OPEN_IND;
+ }
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_mca_create_cfm
+**
+** Description Action routine for processing
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_mca_create_cfm(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tMCA_CREATE_CFM *p_create_cfm = &p_data->mca_evt.mca_data.create_cfm;
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_mca_create_cfm");
+#endif
+
+ if (p_dcb->abort_oper & BTA_HL_ABORT_PENDING_MASK)
+ {
+ p_dcb->abort_oper &= ~BTA_HL_ABORT_PENDING_MASK;
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_ABORT_EVT, p_data);
+ return;
+ }
+
+ if (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_OPEN)
+ {
+ if (p_create_cfm->rsp_code == MCA_RSP_SUCCESS)
+ {
+ if (bta_hl_validate_cfg(app_idx, mcl_idx, mdl_idx, p_create_cfm->cfg ))
+ {
+ bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data);
+
+ if (MCA_DataChnlCfg((tMCA_CL) p_mcb->mcl_handle, &p_dcb->chnl_cfg)!= MCA_SUCCESS)
+ {
+ /* this should not happen */
+ APPL_TRACE_ERROR0("Unable to create data channel");
+ MCA_Abort((tMCA_CL) p_mcb->mcl_handle);
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+ else
+ {
+ if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID)
+ {
+ p_dcb->echo_oper = BTA_HL_ECHO_OP_DCH_OPEN_CFM;
+ }
+ }
+ }
+ else
+ {
+ MCA_Abort((tMCA_CL) p_mcb->mcl_handle);
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+ }
+ else
+ {
+ APPL_TRACE_ERROR0("MCA Create- failed");
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_mca_create
+**
+** Description Action routine for processing the MDL create request
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_mca_create(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ tMCA_RESULT result;
+ UINT8 sdp_idx;
+
+#if BTA_HL_DEBUG == TRUE
+ APPL_TRACE_DEBUG0("bta_hl_dch_mca_create");
+#endif
+
+ if (bta_hl_find_sdp_idx_using_ctrl_psm(&p_mcb->sdp, p_mcb->ctrl_psm, &sdp_idx) &&
+ bta_hl_validate_peer_cfg(app_idx, mcl_idx, mdl_idx,
+ p_dcb->peer_mdep_id,
+ p_dcb->peer_mdep_role,
+ sdp_idx))
+ {
+
+ p_mcb->data_psm = p_mcb->sdp.sdp_rec[sdp_idx].data_psm;
+ if ( (result = MCA_CreateMdl((tMCA_CL) p_mcb->mcl_handle,
+ p_dcb->local_mdep_id,
+ p_mcb->data_psm,
+ p_dcb->mdl_id,
+ p_dcb->peer_mdep_id,
+ p_dcb->local_cfg,
+ NULL )) != MCA_SUCCESS)
+ {
+ APPL_TRACE_ERROR1("MCA_CreateMdl FAIL mca_result=%d", result);
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+ }
+ else
+ {
+ APPL_TRACE_ERROR0("MCA Create- SDP idx or peer MDEP cfg not found");
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_sdp_fail
+**
+** Description Action routine for processing the SDP failed event
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_dch_sdp_fail(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
+ tBTA_HL_DATA *p_data)
+{
+
+#if (BTA_HL_DEBUG == TRUE)
+ APPL_TRACE_DEBUG0("bta_hl_dch_sdp_fail");
+#endif
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+}
+
+/******************************************************************************
+**
+** Function bta_hl_sdp_cback
+**
+** Description This is the SDP callback function used by HL.
+** This function will be executed by SDP when the service
+** search is completed. If the search is successful, it
+** finds the first record in the database that matches the
+** UUID of the search. Then retrieves the scn from the
+** record.
+**
+** Returns void.
+**
+******************************************************************************/
+static void bta_hl_sdp_cback(UINT8 sdp_oper, UINT8 app_idx, UINT8 mcl_idx,
+ UINT8 mdl_idx, UINT16 status)
+{
+ tBTA_HL_MCL_CB *p_cb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_SDP_REC *p_hdp_rec;
+ tBTA_HL_CCH_SDP *p_cch_buf;
+ tBTA_HL_DCH_SDP *p_dch_buf;
+ tSDP_DISC_REC *p_rec = NULL;
+ tSDP_PROTOCOL_ELEM pe;
+ tSDP_DISC_ATTR *p_attr;
+ UINT8 i, rec_cnt;
+ tBTA_HL_SUP_FEATURE_LIST_ELEM sup_feature;
+ BOOLEAN sdp_parsing_ok =FALSE, result=FALSE;
+ UINT16 event;
+ tBTA_HL_MDL_CB *p_dcb;
+ UINT16 service_uuid;
+ UINT16 name_len;
+
+#if BTA_HL_DEBUG == TRUE
+ APPL_TRACE_DEBUG5("bta_hl_sdp_cback status:%d sdp_oper=%d app_idx=%d, mcl_idx=%d, mdl_idx=%d",
+ status, sdp_oper, app_idx, mcl_idx, mdl_idx);
+#endif
+
+ rec_cnt = 0;
+ service_uuid = bta_hl_get_service_uuids(sdp_oper, app_idx, mcl_idx, mdl_idx);
+
+ if (status == SDP_SUCCESS || status == SDP_DB_FULL)
+ {
+ memset(&p_cb->sdp,0, sizeof(tBTA_HL_SDP));
+ do
+ {
+ if (bta_hl_find_service_in_db(app_idx, mcl_idx, service_uuid, &p_rec))
+ {
+ p_hdp_rec = &p_cb->sdp.sdp_rec[rec_cnt];
+ p_cb->sdp.num_recs = rec_cnt+1;
+ }
+ else
+ {
+ break;
+ }
+
+ if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_L2CAP, &pe))
+ {
+ p_hdp_rec->ctrl_psm = (UINT16) pe.params[0];
+ }
+ else
+ {
+ APPL_TRACE_WARNING0("Control PSM not found");
+ break;
+ }
+ if (SDP_FindAddProtoListsElemInRec(p_rec, UUID_PROTOCOL_L2CAP, &pe))
+ {
+ p_hdp_rec->data_psm = (UINT16) pe.params[0];
+ }
+ else
+ {
+ APPL_TRACE_WARNING0("Data PSM not found");
+ break;
+ }
+
+ p_hdp_rec->srv_name[0]= '\0';
+ if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL)
+ {
+ if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) < BT_MAX_SERVICE_NAME_LEN)
+ name_len = (UINT16)SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
+ else
+ name_len = BT_MAX_SERVICE_NAME_LEN;
+ memcpy(p_hdp_rec->srv_name, p_attr->attr_value.v.array, name_len);
+ }
+
+ p_hdp_rec->srv_desp[0]= '\0';
+ if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_DESCRIPTION)) != NULL)
+ {
+ if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) < BT_MAX_SERVICE_NAME_LEN)
+ name_len = (UINT16)SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
+ else
+ name_len = BT_MAX_SERVICE_NAME_LEN;
+ memcpy(p_hdp_rec->srv_desp, p_attr->attr_value.v.array, name_len);
+ }
+
+
+ p_hdp_rec->provider_name[0]= '\0';
+ if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PROVIDER_NAME)) != NULL)
+ {
+ if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) < BT_MAX_SERVICE_NAME_LEN)
+ name_len = (UINT16)SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
+ else
+ name_len = BT_MAX_SERVICE_NAME_LEN;
+ memcpy(p_hdp_rec->provider_name, p_attr->attr_value.v.array, name_len);
+ }
+
+ if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HDP_MCAP_SUP_PROC))!=NULL)
+ {
+ p_hdp_rec->mcap_sup_proc = p_attr->attr_value.v.u8;
+ }
+ else
+ {
+ APPL_TRACE_WARNING0("MCAP SUP PROC not found");
+ break;
+ }
+
+ if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HDP_SUP_FEAT_LIST ))!=NULL)
+ {
+ if (bta_hl_fill_sup_feature_list (p_attr, &sup_feature))
+ {
+ p_hdp_rec->num_mdeps = (UINT8) sup_feature.num_elems;
+ for (i=0; i<sup_feature.num_elems; i++)
+ {
+ p_hdp_rec->mdep_cfg[i].data_type = sup_feature.list_elem[i].data_type;
+ p_hdp_rec->mdep_cfg[i].mdep_id = sup_feature.list_elem[i].mdep_id;
+ p_hdp_rec->mdep_cfg[i].mdep_role = sup_feature.list_elem[i].mdep_role;
+ /* Check MDEP Description pointer to prevent crash due to null pointer */
+ if (sup_feature.list_elem[i].p_mdep_desp != NULL)
+ {
+ BCM_STRNCPY_S(p_hdp_rec->mdep_cfg[i].mdep_desp,
+ sizeof(p_hdp_rec->mdep_cfg[i].mdep_desp),
+ sup_feature.list_elem[i].p_mdep_desp,
+ BTA_HL_MDEP_DESP_LEN);
+ }
+ else
+ {
+ APPL_TRACE_ERROR1("bta_hl_sdp_cback Incorrect Mdep[%d] Description (Null ptr)", i);
+ }
+ }
+
+ sdp_parsing_ok = TRUE;
+ }
+ else
+ {
+ APPL_TRACE_WARNING0("HDP supported feature list fill failed");
+ break;
+ }
+ }
+ else
+ {
+ APPL_TRACE_WARNING0("HDP supported feature list not found");
+ break;
+ }
+#if BTA_HL_DEBUG == TRUE
+ APPL_TRACE_DEBUG3("record=%d ctrl_psm=%0x data_psm=%x",
+ rec_cnt+1,
+ p_hdp_rec->ctrl_psm,
+ p_hdp_rec->data_psm );
+ APPL_TRACE_DEBUG1("srv_name=[%s]",(p_hdp_rec->srv_name[0] != '\0')? p_hdp_rec->srv_name:"NULL");
+ APPL_TRACE_DEBUG1("srv_desp=[%s]",(p_hdp_rec->srv_desp[0] != '\0')? p_hdp_rec->srv_desp:"NULL");
+ for (i=0; i<sup_feature.num_elems; i++)
+ {
+ APPL_TRACE_DEBUG5("index=0x%02x mdep_id=0x%04x data type=0x%04x mdep role=%s(0x%02x)",
+ (i+1),
+ p_hdp_rec->mdep_cfg[i].mdep_id,
+ p_hdp_rec->mdep_cfg[i].data_type,
+ (p_hdp_rec->mdep_cfg[i].mdep_role == BTA_HL_MDEP_ROLE_SOURCE)?"Src":"Snk",
+ p_hdp_rec->mdep_cfg[i].mdep_role);
+ }
+ APPL_TRACE_DEBUG1("provider_name=[%s]",(p_hdp_rec->provider_name[0] != '\0')? p_hdp_rec->provider_name:"NULL");
+ APPL_TRACE_DEBUG1("found MCAP sup procedure=%d",
+ p_cb->sdp.sdp_rec[rec_cnt].mcap_sup_proc );
+#endif
+ rec_cnt++;
+ if (rec_cnt >= BTA_HL_NUM_SDP_RECS)
+ {
+ APPL_TRACE_WARNING1("No more spaces for SDP recs max_rec_cnt=%d", BTA_HL_NUM_SDP_RECS);
+ break;
+ }
+
+
+ } while (TRUE);
+ }
+
+
+ utl_freebuf((void **)&p_cb->p_db);
+
+ if ( (status == SDP_SUCCESS || status == SDP_DB_FULL) &&
+ p_cb->sdp.num_recs &&
+ sdp_parsing_ok)
+ {
+ result = TRUE;
+ }
+ else
+ {
+ APPL_TRACE_WARNING3("SDP Failed sdp_status=%d num_recs=%d sdp_parsing_ok=%d ",
+ status, p_cb->sdp.num_recs,sdp_parsing_ok );
+ }
+
+
+ p_cb->sdp_oper = BTA_HL_SDP_OP_NONE;
+
+ switch (sdp_oper )
+ {
+ case BTA_HL_SDP_OP_CCH_INIT:
+ case BTA_HL_SDP_OP_SDP_QUERY_NEW:
+ case BTA_HL_SDP_OP_SDP_QUERY_CURRENT:
+
+ /* send result in event back to BTA */
+ if ((p_cch_buf = (tBTA_HL_CCH_SDP *) GKI_getbuf(sizeof(tBTA_HL_CCH_SDP))) != NULL)
+ {
+ if (result)
+ {
+ if (sdp_oper == BTA_HL_SDP_OP_CCH_INIT)
+ {
+ event = BTA_HL_CCH_SDP_OK_EVT;
+ if (p_cb->close_pending)
+ {
+ event = BTA_HL_CCH_SDP_FAIL_EVT;
+ }
+ }
+ else
+ {
+ event = BTA_HL_SDP_QUERY_OK_EVT;
+ }
+ }
+ else
+ {
+ if (sdp_oper == BTA_HL_SDP_OP_CCH_INIT)
+ {
+ event = BTA_HL_CCH_SDP_FAIL_EVT;
+ }
+ else
+ {
+ event = BTA_HL_SDP_QUERY_FAIL_EVT;
+ }
+ }
+ p_cch_buf->hdr.event = event;
+
+ p_cch_buf->app_idx = app_idx;
+ p_cch_buf->mcl_idx = mcl_idx;
+ p_cch_buf->release_mcl_cb = FALSE;
+ if (sdp_oper == BTA_HL_SDP_OP_SDP_QUERY_NEW)
+ {
+ p_cch_buf->release_mcl_cb = TRUE;
+ }
+
+ bta_sys_sendmsg(p_cch_buf);
+ }
+ break;
+ case BTA_HL_SDP_OP_DCH_OPEN_INIT:
+ case BTA_HL_SDP_OP_DCH_RECONNECT_INIT:
+ if ((p_dch_buf = (tBTA_HL_DCH_SDP *) GKI_getbuf(sizeof(tBTA_HL_DCH_SDP))) != NULL)
+ {
+ p_dch_buf->hdr.event = BTA_HL_DCH_SDP_FAIL_EVT;
+ p_dch_buf->app_idx = app_idx;
+ p_dch_buf->mcl_idx = mcl_idx;
+ p_dch_buf->mdl_idx = mdl_idx;
+ p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
+ if (p_dcb->abort_oper & BTA_HL_ABORT_PENDING_MASK)
+ {
+ p_dcb->abort_oper &= ~BTA_HL_ABORT_PENDING_MASK;
+ result = FALSE;
+ }
+ if (result)
+ {
+ if (sdp_oper == BTA_HL_SDP_OP_DCH_OPEN_INIT)
+ {
+ if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID )
+ {
+ p_dch_buf->hdr.event = BTA_HL_DCH_ECHO_TEST_EVT;
+ }
+ else
+ {
+ p_dch_buf->hdr.event = BTA_HL_DCH_OPEN_EVT;
+ }
+ }
+ else
+ {
+ p_dch_buf->hdr.event = BTA_HL_DCH_RECONNECT_EVT;
+ }
+ }
+ bta_sys_sendmsg(p_dch_buf);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+
+/******************************************************************************
+**
+** Function bta_hl_sdp_cback0
+**
+** Description This is the SDP callback function used by index = 0
+**
+** Returns void.
+**
+******************************************************************************/
+static void bta_hl_sdp_cback0(UINT16 status)
+{
+ bta_hl_sdp_cback(bta_hl_cb.scb[0].sdp_oper,
+ bta_hl_cb.scb[0].app_idx,
+ bta_hl_cb.scb[0].mcl_idx,
+ bta_hl_cb.scb[0].mdl_idx,
+ status);
+ bta_hl_deallocate_spd_cback(0);
+}
+
+/******************************************************************************
+**
+** Function bta_hl_sdp_cback1
+**
+** Description This is the SDP callback function used by index = 1
+**
+** Parameters status - status of the SDP callabck
+**
+** Returns void.
+**
+******************************************************************************/
+static void bta_hl_sdp_cback1(UINT16 status)
+{
+ bta_hl_sdp_cback(bta_hl_cb.scb[1].sdp_oper,
+ bta_hl_cb.scb[1].app_idx,
+ bta_hl_cb.scb[1].mcl_idx,
+ bta_hl_cb.scb[1].mdl_idx,
+ status);
+ bta_hl_deallocate_spd_cback(1);
+}
+
+/******************************************************************************
+**
+** Function bta_hl_sdp_cback2
+**
+** Description This is the SDP callback function used by index = 2
+**
+** Returns void.
+**
+******************************************************************************/
+static void bta_hl_sdp_cback2(UINT16 status)
+{
+ bta_hl_sdp_cback(bta_hl_cb.scb[2].sdp_oper,
+ bta_hl_cb.scb[2].app_idx,
+ bta_hl_cb.scb[2].mcl_idx,
+ bta_hl_cb.scb[2].mdl_idx,
+ status);
+ bta_hl_deallocate_spd_cback(2);
+}
+
+/******************************************************************************
+**
+** Function bta_hl_sdp_cback3
+**
+** Description This is the SDP callback function used by index = 3
+**
+** Returns void.
+**
+******************************************************************************/
+static void bta_hl_sdp_cback3(UINT16 status)
+{
+ bta_hl_sdp_cback(bta_hl_cb.scb[3].sdp_oper,
+ bta_hl_cb.scb[3].app_idx,
+ bta_hl_cb.scb[3].mcl_idx,
+ bta_hl_cb.scb[3].mdl_idx,
+ status);
+ bta_hl_deallocate_spd_cback(3);
+}
+
+/******************************************************************************
+**
+** Function bta_hl_sdp_cback4
+**
+** Description This is the SDP callback function used by index = 4
+**
+** Parameters status - status of the SDP callabck
+**
+** Returns void.
+**
+******************************************************************************/
+static void bta_hl_sdp_cback4(UINT16 status)
+{
+ bta_hl_sdp_cback(bta_hl_cb.scb[4].sdp_oper,
+ bta_hl_cb.scb[4].app_idx,
+ bta_hl_cb.scb[4].mcl_idx,
+ bta_hl_cb.scb[4].mdl_idx,
+ status);
+ bta_hl_deallocate_spd_cback(4);
+}
+
+/******************************************************************************
+**
+** Function bta_hl_sdp_cback5
+**
+** Description This is the SDP callback function used by index = 5
+**
+** Parameters status - status of the SDP callabck
+**
+** Returns void.
+**
+******************************************************************************/
+static void bta_hl_sdp_cback5(UINT16 status)
+{
+ bta_hl_sdp_cback(bta_hl_cb.scb[5].sdp_oper,
+ bta_hl_cb.scb[5].app_idx,
+ bta_hl_cb.scb[5].mcl_idx,
+ bta_hl_cb.scb[5].mdl_idx,
+ status);
+ bta_hl_deallocate_spd_cback(5);
+}
+
+/******************************************************************************
+**
+** Function bta_hl_sdp_cback6
+**
+** Description This is the SDP callback function used by index = 6
+**
+** Returns void.
+**
+******************************************************************************/
+static void bta_hl_sdp_cback6(UINT16 status)
+{
+ bta_hl_sdp_cback(bta_hl_cb.scb[6].sdp_oper,
+ bta_hl_cb.scb[6].app_idx,
+ bta_hl_cb.scb[6].mcl_idx,
+ bta_hl_cb.scb[6].mdl_idx,
+ status);
+ bta_hl_deallocate_spd_cback(6);
+}
+
+
+/*******************************************************************************
+**
+** Function bta_hl_deallocate_spd_cback
+**
+** Description Deallocate a SDP control block
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+**
+*******************************************************************************/
+void bta_hl_deallocate_spd_cback(UINT8 sdp_cback_idx)
+{
+ tBTA_HL_SDP_CB *p_spd_cb = &bta_hl_cb.scb[sdp_cback_idx];
+
+ memset(p_spd_cb, 0, sizeof(tBTA_HL_SDP_CB));
+
+#if BTA_HL_DEBUG == TRUE
+ APPL_TRACE_DEBUG1("bta_hl_deallocate_spd_cback index=%d", sdp_cback_idx);
+#endif
+
+
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_allocate_spd_cback
+**
+** Description Finds a not in used SDP control block index
+**
+**
+** Returns BOOLEAN - TRUE found
+** FALSE not found
+**
+*******************************************************************************/
+tSDP_DISC_CMPL_CB *bta_hl_allocate_spd_cback(tBTA_HL_SDP_OPER sdp_oper, UINT8 app_idx, UINT8 mcl_idx,
+ UINT8 mdl_idx,
+ UINT8 *p_sdp_cback_idx)
+{
+ UINT8 i;
+ tSDP_DISC_CMPL_CB *p_cbcak=NULL;
+
+
+ for (i=0; i < BTA_HL_NUM_SDP_CBACKS ; i ++)
+ {
+ if (!bta_hl_cb.scb[i].in_use)
+ {
+ p_cbcak = bta_hl_sdp_cback_arr[i];
+ bta_hl_cb.scb[i].in_use = TRUE;
+ bta_hl_cb.scb[i].sdp_oper = sdp_oper;
+ bta_hl_cb.scb[i].app_idx = app_idx;
+ bta_hl_cb.scb[i].mcl_idx = mcl_idx;
+ bta_hl_cb.scb[i].mdl_idx = mdl_idx;
+ *p_sdp_cback_idx = i;
+ break;
+ }
+ }
+
+ if (i == BTA_HL_NUM_SDP_CBACKS)
+ {
+ APPL_TRACE_WARNING0("No scb is available to allocate")
+ }
+ else
+ {
+#if BTA_HL_DEBUG == TRUE
+ APPL_TRACE_DEBUG1("bta_hl_allocate_spd_cback cback_idx=%d ",i );
+ APPL_TRACE_DEBUG4("sdp_oper=%d, app_idx=%d, mcl_idx=%d, mdl_idx=%d",
+ bta_hl_cb.scb[i].sdp_oper,
+ bta_hl_cb.scb[i].app_idx,
+ bta_hl_cb.scb[i].mcl_idx,
+ bta_hl_cb.scb[i].mdl_idx );
+#endif
+ }
+ return p_cbcak;
+}
+
+
+/*******************************************************************************
+**
+** Function bta_hl_init_sdp
+**
+** Description Action routine for processing the SDP initiattion request
+**
+** Returns void
+**
+*******************************************************************************/
+tBTA_HL_STATUS bta_hl_init_sdp(tBTA_HL_SDP_OPER sdp_oper, UINT8 app_idx, UINT8 mcl_idx,
+ UINT8 mdl_idx)
+{
+ tBTA_HL_MCL_CB *p_cb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tSDP_UUID uuid_list;
+ UINT16 attr_list[BTA_HL_NUM_SRCH_ATTR];
+ UINT16 num_attrs = BTA_HL_NUM_SRCH_ATTR;
+ tBTA_HL_STATUS status;
+ UINT8 sdp_cback_idx;
+#if BTA_HL_DEBUG == TRUE
+ APPL_TRACE_DEBUG4("bta_hl_init_sdp sdp_oper=%d app_idx=%d mcl_idx=%d, mdl_idx=%d",
+ sdp_oper, app_idx, mcl_idx, mdl_idx);
+#endif
+ if ((p_cb->sdp_cback = bta_hl_allocate_spd_cback(sdp_oper, app_idx, mcl_idx, mdl_idx, &sdp_cback_idx)) != NULL)
+ {
+ if ( p_cb->p_db ||
+ (!p_cb->p_db &&
+ (p_cb->p_db = (tSDP_DISCOVERY_DB *) GKI_getbuf(BTA_HL_DISC_SIZE)) != NULL))
+ {
+ attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
+ attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
+ attr_list[2] = ATTR_ID_BT_PROFILE_DESC_LIST;
+ attr_list[3] = ATTR_ID_ADDITION_PROTO_DESC_LISTS;
+ attr_list[4] = ATTR_ID_SERVICE_NAME;
+ attr_list[5] = ATTR_ID_SERVICE_DESCRIPTION;
+ attr_list[6] = ATTR_ID_PROVIDER_NAME;
+ attr_list[7] = ATTR_ID_HDP_SUP_FEAT_LIST;
+ attr_list[8] = ATTR_ID_HDP_DATA_EXCH_SPEC;
+ attr_list[9] = ATTR_ID_HDP_MCAP_SUP_PROC;
+
+
+ uuid_list.len = LEN_UUID_16;
+ uuid_list.uu.uuid16 = UUID_SERVCLASS_HDP_PROFILE;
+
+ SDP_InitDiscoveryDb(p_cb->p_db, BTA_HL_DISC_SIZE, 1, &uuid_list, num_attrs, attr_list);
+
+ if (!SDP_ServiceSearchAttributeRequest(p_cb->bd_addr, p_cb->p_db, p_cb->sdp_cback))
+ {
+ status = BTA_HL_STATUS_FAIL;
+ }
+ else
+ {
+ status = BTA_HL_STATUS_OK;
+ }
+ }
+ else /* No services available */
+ {
+ status = BTA_HL_STATUS_NO_RESOURCE;
+ }
+ }
+ else
+ {
+ status = BTA_HL_STATUS_SDP_NO_RESOURCE;
+ }
+
+ if (status != BTA_HL_STATUS_OK)
+ {
+ utl_freebuf((void **)&p_cb->p_db);
+ if (status != BTA_HL_STATUS_SDP_NO_RESOURCE )
+ {
+ bta_hl_deallocate_spd_cback(sdp_cback_idx);
+ }
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_cch_sdp_init
+**
+** Description Action routine for processing the CCH SDP init event
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_cch_sdp_init(UINT8 app_idx, UINT8 mcl_idx, tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_MCL_CB *p_cb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+#if BTA_HL_DEBUG == TRUE
+ APPL_TRACE_DEBUG0("bta_hl_cch_init_sdp");
+#endif
+ if ( p_cb->sdp_oper == BTA_HL_SDP_OP_NONE)
+ {
+ p_cb->sdp_oper = BTA_HL_SDP_OP_CCH_INIT;
+
+ if (bta_hl_init_sdp( p_cb->sdp_oper, app_idx, mcl_idx, 0xFF) != BTA_HL_STATUS_OK)
+ {
+ p_cb->sdp_oper = BTA_HL_SDP_OP_NONE;
+ bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_SDP_FAIL_EVT, p_data);
+ }
+ }
+ else
+ {
+ APPL_TRACE_ERROR0("SDP in use");
+ bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_SDP_FAIL_EVT, p_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_cch_mca_open
+**
+** Description Action routine for processing the CCH open request
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_cch_mca_open(UINT8 app_idx, UINT8 mcl_idx, tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ UINT8 sdp_idx;
+
+#if BTA_HL_DEBUG == TRUE
+ APPL_TRACE_DEBUG0("bta_hl_cch_mca_open");
+#endif
+
+ if (bta_hl_find_sdp_idx_using_ctrl_psm(&p_mcb->sdp, p_mcb->req_ctrl_psm, &sdp_idx))
+ {
+ p_mcb->ctrl_psm = p_mcb->sdp.sdp_rec[sdp_idx].ctrl_psm;
+ p_mcb->data_psm = p_mcb->sdp.sdp_rec[sdp_idx].data_psm;
+ if ( MCA_ConnectReq((tMCA_HANDLE) p_acb->app_handle,
+ p_mcb->bd_addr,
+ p_mcb->ctrl_psm ,
+ p_mcb->sec_mask) != MCA_SUCCESS)
+ {
+
+ bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_CMPL_EVT, p_data);
+ }
+ }
+ else
+ {
+ bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_CMPL_EVT, p_data);
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_cch_mca_close
+**
+** Description Action routine for processing the CCH close request
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_cch_mca_close(UINT8 app_idx, UINT8 mcl_idx, tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+
+#if BTA_HL_DEBUG == TRUE
+ APPL_TRACE_DEBUG0("bta_hl_cch_mca_close");
+#endif
+ if (p_mcb->sdp_oper != BTA_HL_SDP_OP_CCH_INIT)
+ {
+ if ( MCA_DisconnectReq((tMCA_HANDLE) p_acb->app_handle) != MCA_SUCCESS)
+ {
+ bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_CMPL_EVT, p_data);
+ }
+ }
+ else
+ {
+ p_mcb->close_pending = TRUE;
+ }
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_cch_close_cmpl
+**
+** Description Action routine for processing the CCH close complete event
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_cch_close_cmpl(UINT8 app_idx, UINT8 mcl_idx, tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+
+ tBTA_HL evt_data;
+ tBTA_HL_EVT event;
+ BOOLEAN send_evt=TRUE;
+#if BTA_HL_DEBUG == TRUE
+ APPL_TRACE_DEBUG0("bta_hl_cch_close_cmpl");
+#endif
+ bta_sys_conn_close(BTA_ID_HL, p_acb->app_id, p_mcb->bd_addr);
+
+ switch (p_mcb->cch_oper)
+ {
+ case BTA_HL_CCH_OP_LOCAL_OPEN:
+ bta_hl_build_cch_open_cfm(&evt_data, p_acb->app_handle,
+ p_mcb->mcl_handle,
+ p_mcb->bd_addr,
+ BTA_HL_STATUS_FAIL);
+ event = BTA_HL_CCH_OPEN_CFM_EVT;
+ break;
+ case BTA_HL_CCH_OP_LOCAL_CLOSE:
+ bta_hl_build_cch_close_cfm(&evt_data, p_acb->app_handle,
+ p_mcb->mcl_handle,
+ BTA_HL_STATUS_OK);
+ event = BTA_HL_CCH_CLOSE_CFM_EVT;
+ break;
+ case BTA_HL_CCH_OP_REMOTE_CLOSE:
+ bta_hl_build_cch_close_ind(&evt_data,
+ p_acb->app_handle,
+ p_mcb->mcl_handle,
+ p_mcb->intentional_close);
+ event = BTA_HL_CCH_CLOSE_IND_EVT;
+ break;
+ default:
+ send_evt=FALSE;
+ break;
+ }
+
+
+ memset(p_mcb, 0 ,sizeof(tBTA_HL_MCL_CB));
+
+ if (send_evt)p_acb->p_cback(event,(tBTA_HL *) &evt_data );
+
+ bta_hl_check_deregistration(app_idx, p_data);
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_cch_mca_disconnect
+**
+** Description Action routine for processing the CCH disconnect indication
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_cch_mca_disconnect(UINT8 app_idx, UINT8 mcl_idx, tBTA_HL_DATA *p_data)
+{
+
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL_MDL_CB *p_dcb;
+ UINT8 i;
+#if BTA_HL_DEBUG == TRUE
+ APPL_TRACE_DEBUG0("bta_hl_cch_mca_disconnect");
+#endif
+
+ p_mcb->intentional_close = FALSE;
+ if (p_data->mca_evt.mca_data.disconnect_ind.reason == L2CAP_DISC_OK)
+ {
+ p_mcb->intentional_close = TRUE;
+ }
+
+ for (i=0; i< BTA_HL_NUM_MDLS_PER_MCL; i++)
+ {
+ p_dcb= BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, i);
+ if (p_dcb->in_use && (p_dcb->dch_state != BTA_HL_DCH_IDLE_ST))
+ {
+ if (p_mcb->cch_oper == BTA_HL_CCH_OP_LOCAL_CLOSE )
+ {
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, i, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
+ }
+ else
+ {
+ bta_hl_dch_sm_execute(app_idx, mcl_idx, i, BTA_HL_MCA_CLOSE_IND_EVT, p_data);
+ }
+ }
+ }
+ bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_CMPL_EVT, p_data);
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_cch_mca_rsp_tout
+**
+** Description Action routine for processing the MCAP response timeout
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_cch_mca_rsp_tout(UINT8 app_idx, UINT8 mcl_idx, tBTA_HL_DATA *p_data)
+{
+
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+#if BTA_HL_DEBUG == TRUE
+ APPL_TRACE_DEBUG0("bta_hl_cch_mca_rsp_tout");
+#endif
+
+ p_mcb->rsp_tout = TRUE;
+
+ bta_hl_check_cch_close(app_idx,mcl_idx,p_data,TRUE);
+}
+/*******************************************************************************
+**
+** Function bta_hl_cch_mca_connect
+**
+** Description Action routine for processing the CCH connect indication
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_cch_mca_connect(UINT8 app_idx, UINT8 mcl_idx, tBTA_HL_DATA *p_data)
+{
+ tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
+ tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
+ tBTA_HL evt_data;
+ tBTA_HL_EVT event;
+ BOOLEAN send_event=TRUE;
+
+#if BTA_HL_DEBUG == TRUE
+ APPL_TRACE_DEBUG0("bta_hl_cch_mca_connect");
+#endif
+
+ p_mcb->mcl_handle = p_data->mca_evt.mcl_handle;
+ bdcpy(p_mcb->bd_addr, p_data->mca_evt.mca_data.connect_ind.bd_addr);
+ p_mcb->cch_mtu = p_data->mca_evt.mca_data.connect_ind.mtu;
+
+ bta_sys_conn_open(BTA_ID_HL, p_acb->app_id, p_mcb->bd_addr);
+ switch (p_mcb->cch_oper)
+ {
+ case BTA_HL_CCH_OP_LOCAL_OPEN:
+ bta_hl_build_cch_open_cfm(&evt_data, p_acb->app_handle,
+ p_mcb->mcl_handle,
+ p_mcb->bd_addr,
+ BTA_HL_STATUS_OK);
+ event = BTA_HL_CCH_OPEN_CFM_EVT;
+ break;
+ case BTA_HL_CCH_OP_REMOTE_OPEN:
+ bta_hl_build_cch_open_ind(&evt_data, p_acb->app_handle,
+ p_mcb->mcl_handle,
+ p_mcb->bd_addr);
+ event = BTA_HL_CCH_OPEN_IND_EVT;
+ break;
+ default:
+ send_event = FALSE;
+ break;
+ }
+
+ p_mcb->cch_oper = BTA_HL_CCH_OP_NONE;
+ if (send_event) p_acb->p_cback(event,(tBTA_HL *) &evt_data );
+}
+
+/*******************************************************************************
+**
+** Function bta_hl_mcap_ctrl_cback
+**
+** Description MCAP control callback function for HL.
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_mcap_ctrl_cback (tMCA_HANDLE handle, tMCA_CL mcl, UINT8 event,
+ tMCA_CTRL *p_data)
+{
+ tBTA_HL_MCA_EVT * p_msg;
+ BOOLEAN send_event=TRUE;
+ UINT16 mca_event;
+
+#if (BTA_HL_DEBUG == TRUE)
+#if (BT_TRACE_VERBOSE == TRUE)
+ APPL_TRACE_EVENT1("bta_hl_mcap_ctrl_cback event[%s]",bta_hl_mcap_evt_code(event));
+#else
+ APPL_TRACE_EVENT1("bta_hl_mcap_ctrl_cback event[0x%02x]", event);
+#endif
+#endif
+
+ switch (event)
+ {
+
+ case MCA_CREATE_IND_EVT:
+ mca_event = (UINT16) BTA_HL_MCA_CREATE_IND_EVT;
+ break;
+ case MCA_CREATE_CFM_EVT:
+ mca_event = (UINT16) BTA_HL_MCA_CREATE_CFM_EVT;
+ break;
+ case MCA_RECONNECT_IND_EVT:
+ mca_event = (UINT16) BTA_HL_MCA_RECONNECT_IND_EVT;
+ break;
+ case MCA_RECONNECT_CFM_EVT:
+ mca_event = (UINT16) BTA_HL_MCA_RECONNECT_CFM_EVT;
+ break;
+ case MCA_ABORT_IND_EVT:
+ mca_event = (UINT16) BTA_HL_MCA_ABORT_IND_EVT;
+ break;
+ case MCA_ABORT_CFM_EVT:
+ mca_event = (UINT16) BTA_HL_MCA_ABORT_CFM_EVT;
+ break;
+ case MCA_DELETE_IND_EVT:
+ mca_event = (UINT16) BTA_HL_MCA_DELETE_IND_EVT;
+ break;
+ case MCA_DELETE_CFM_EVT:
+ mca_event = (UINT16) BTA_HL_MCA_DELETE_CFM_EVT;
+ break;
+ case MCA_CONNECT_IND_EVT:
+ mca_event = (UINT16) BTA_HL_MCA_CONNECT_IND_EVT;
+ break;
+ case MCA_DISCONNECT_IND_EVT:
+ mca_event = (UINT16) BTA_HL_MCA_DISCONNECT_IND_EVT;
+ break;
+ case MCA_OPEN_IND_EVT:
+ mca_event = (UINT16) BTA_HL_MCA_OPEN_IND_EVT;
+ break;
+ case MCA_OPEN_CFM_EVT:
+ mca_event = (UINT16) BTA_HL_MCA_OPEN_CFM_EVT;
+ break;
+ case MCA_CLOSE_IND_EVT:
+ mca_event = (UINT16) BTA_HL_MCA_CLOSE_IND_EVT;
+ break;
+ case MCA_CLOSE_CFM_EVT:
+ mca_event = (UINT16) BTA_HL_MCA_CLOSE_CFM_EVT;
+ break;
+ case MCA_CONG_CHG_EVT:
+ mca_event = (UINT16) BTA_HL_MCA_CONG_CHG_EVT;
+ break;
+ case MCA_RSP_TOUT_IND_EVT:
+ mca_event = (UINT16) BTA_HL_MCA_RSP_TOUT_IND_EVT;
+ break;
+ case MCA_ERROR_RSP_EVT:
+
+ default:
+ send_event=FALSE;
+ break;
+ }
+
+ if ((p_msg = (tBTA_HL_MCA_EVT *)GKI_getbuf(sizeof(tBTA_HL_MCA_EVT))) != NULL)
+ {
+ p_msg->hdr.event = mca_event;
+ p_msg->app_handle = (tBTA_HL_APP_HANDLE) handle;
+ p_msg->mcl_handle = (tBTA_HL_MCL_HANDLE) mcl;
+ memcpy (&p_msg->mca_data, p_data, sizeof(tMCA_CTRL));
+ bta_sys_sendmsg(p_msg);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function bta_hl_mcap_data_cback
+**
+** Description MCAP data callback function for HL.
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_hl_mcap_data_cback (tMCA_DL mdl, BT_HDR *p_pkt)
+{
+ tBTA_HL_MCA_RCV_DATA_EVT *p_msg;
+
+ UINT8 app_idx, mcl_idx, mdl_idx;
+ if (bta_hl_find_mdl_idx_using_handle ((tBTA_HL_MDL_HANDLE)mdl, &app_idx, &mcl_idx, &mdl_idx))
+ {
+ if ((p_msg = (tBTA_HL_MCA_RCV_DATA_EVT *)GKI_getbuf(sizeof(tBTA_HL_MCA_RCV_DATA_EVT))) != NULL)
+ {
+ p_msg->hdr.event = BTA_HL_MCA_RCV_DATA_EVT;
+ p_msg->app_idx = app_idx;
+ p_msg->mcl_idx = mcl_idx;
+ p_msg->mdl_idx = mdl_idx;
+ p_msg->p_pkt = p_pkt;
+ bta_sys_sendmsg(p_msg);
+ }
+ }
+}
+/*****************************************************************************
+** Debug Functions
+*****************************************************************************/
+#if (BTA_HL_DEBUG == TRUE && BT_TRACE_VERBOSE == TRUE)
+
+/*******************************************************************************
+**
+** Function bta_hl_mcap_evt_code
+**
+** Description get the MCAP event string pointer
+**
+** Returns char * - event string pointer
+**
+*******************************************************************************/
+static char *bta_hl_mcap_evt_code(UINT8 evt_code)
+{
+
+ switch (evt_code)
+ {
+
+ case MCA_ERROR_RSP_EVT:
+ return "MCA_ERROR_RSP_EVT";
+ case MCA_CREATE_IND_EVT:
+ return "MCA_CREATE_IND_EVT";
+ case MCA_CREATE_CFM_EVT:
+ return "MCA_CREATE_CFM_EVT";
+ case MCA_RECONNECT_IND_EVT:
+ return "MCA_RECONNECT_IND_EVT";
+ case MCA_RECONNECT_CFM_EVT:
+ return "MCA_RECONNECT_CFM_EVT";
+ case MCA_ABORT_IND_EVT:
+ return "MCA_ABORT_IND_EVT";
+ case MCA_ABORT_CFM_EVT:
+ return "MCA_ABORT_CFM_EVT";
+ case MCA_DELETE_IND_EVT:
+ return "MCA_DELETE_IND_EVT";
+ case MCA_DELETE_CFM_EVT:
+ return "MCA_DELETE_CFM_EVT";
+
+ case MCA_CONNECT_IND_EVT:
+ return "MCA_CONNECT_IND_EVT";
+ case MCA_DISCONNECT_IND_EVT:
+ return "MCA_DISCONNECT_IND_EVT";
+ case MCA_OPEN_IND_EVT:
+ return "MCA_OPEN_IND_EVT";
+ case MCA_OPEN_CFM_EVT:
+ return "MCA_OPEN_CFM_EVT";
+ case MCA_CLOSE_IND_EVT:
+ return "MCA_CLOSE_IND_EVT";
+ case MCA_CLOSE_CFM_EVT:
+ return "MCA_CLOSE_CFM_EVT";
+ case MCA_CONG_CHG_EVT:
+ return "MCA_CONG_CHG_EVT";
+ case MCA_RSP_TOUT_IND_EVT:
+ return "MCA_RSP_TOUT_IND_EVT";
+ default:
+ return "Unknown MCAP event code";
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function bta_hl_cback_evt_code
+**
+** Description get the HDP event string pointer
+**
+** Returns char * - event string pointer
+**
+*******************************************************************************/
+static char *bta_hl_cback_evt_code(UINT8 evt_code)
+{
+
+ switch (evt_code)
+ {
+
+ case BTA_HL_CCH_OPEN_IND_EVT:
+ return "BTA_HL_CCH_OPEN_IND_EVT";
+ case BTA_HL_CCH_OPEN_CFM_EVT:
+ return "BTA_HL_CCH_OPEN_CFM_EVT";
+ case BTA_HL_CCH_CLOSE_IND_EVT:
+ return "BTA_HL_CCH_CLOSE_IND_EVT";
+ case BTA_HL_CCH_CLOSE_CFM_EVT:
+ return "BTA_HL_CCH_CLOSE_CFM_EVT";
+ case BTA_HL_DCH_OPEN_IND_EVT:
+ return "BTA_HL_DCH_OPEN_IND_EVT";
+ case BTA_HL_DCH_OPEN_CFM_EVT:
+ return "BTA_HL_DCH_OPEN_CFM_EVT";
+ case BTA_HL_DCH_CLOSE_IND_EVT:
+ return "BTA_HL_DCH_CLOSE_IND_EVT";
+ case BTA_HL_DCH_CLOSE_CFM_EVT:
+ return "BTA_HL_DCH_CLOSE_CFM_EVT";
+ case BTA_HL_DCH_RCV_DATA_IND_EVT:
+ return "BTA_HL_DCH_RCV_DATA_IND_EVT";
+ case BTA_HL_REGISTER_CFM_EVT:
+ return "BTA_HL_REGISTER_CFM_EVT";
+ case BTA_HL_DEREGISTER_CFM_EVT:
+ return "BTA_HL_DEREGISTER_CFM_EVT";
+ case BTA_HL_DCH_RECONNECT_CFM_EVT:
+ return "BTA_HL_DCH_RECONNECT_CFM_EVT";
+ case BTA_HL_DCH_RECONNECT_IND_EVT:
+ return "BTA_HL_DCH_RECONNECT_IND_EVT";
+ case BTA_HL_DCH_ECHO_TEST_CFM_EVT:
+ return "BTA_HL_DCH_ECHO_TEST_CFM_EVT";
+ case BTA_HL_SDP_QUERY_CFM_EVT:
+ return "BTA_HL_SDP_QUERY_CFM_EVT";
+ case BTA_HL_CONG_CHG_IND_EVT:
+ return "BTA_HL_CONG_CHG_IND_EVT";
+ case BTA_HL_DCH_CREATE_IND_EVT:
+ return "BTA_HL_DCH_CREATE_IND_EVT";
+ case BTA_HL_DELETE_MDL_IND_EVT:
+ return "BTA_HL_DELETE_MDL_IND_EVT";
+ case BTA_HL_DELETE_MDL_CFM_EVT:
+ return "BTA_HL_DELETE_MDL_CFM_EVT";
+ case BTA_HL_DCH_ABORT_IND_EVT:
+ return "BTA_HL_DCH_ABORT_IND_EVT";
+ case BTA_HL_DCH_ABORT_CFM_EVT:
+ return "BTA_HL_DCH_ABORT_CFM_EVT";
+ default:
+ return "Unknown HDP event code";
+ }
+}
+
+
+
+/*******************************************************************************
+**
+** Function bta_hl_dch_oper_code
+**
+** Description Get the DCH operation string
+**
+** Returns char * - DCH operation string pointer
+**
+*******************************************************************************/
+static char *bta_hl_dch_oper_code(tBTA_HL_DCH_OPER oper_code)
+{
+
+ switch (oper_code)
+ {
+ case BTA_HL_DCH_OP_NONE:
+ return "BTA_HL_DCH_OP_NONE";
+ case BTA_HL_DCH_OP_REMOTE_CREATE:
+ return "BTA_HL_DCH_OP_REMOTE_CREATE";
+ case BTA_HL_DCH_OP_LOCAL_OPEN:
+ return "BTA_HL_DCH_OP_LOCAL_OPEN";
+ case BTA_HL_DCH_OP_REMOTE_OPEN:
+ return "BTA_HL_DCH_OP_REMOTE_OPEN";
+ case BTA_HL_DCH_OP_LOCAL_CLOSE:
+ return "BTA_HL_DCH_OP_LOCAL_CLOSE";
+ case BTA_HL_DCH_OP_REMOTE_CLOSE:
+ return "BTA_HL_DCH_OP_REMOTE_CLOSE";
+ case BTA_HL_DCH_OP_LOCAL_DELETE:
+ return "BTA_HL_DCH_OP_LOCAL_DELETE";
+ case BTA_HL_DCH_OP_REMOTE_DELETE:
+ return "BTA_HL_DCH_OP_REMOTE_DELETE";
+ case BTA_HL_DCH_OP_LOCAL_RECONNECT:
+ return "BTA_HL_DCH_OP_LOCAL_RECONNECT";
+ case BTA_HL_DCH_OP_REMOTE_RECONNECT:
+ return "BTA_HL_DCH_OP_REMOTE_RECONNECT";
+ case BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST:
+ return "BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST";
+ case BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT:
+ return "BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT";
+ default:
+ return "Unknown DCH oper code";
+ }
+}
+
+
+#endif /* Debug Functions */
+#endif /* HL_INCLUDED */