Home | History | Annotate | Download | only in hl
      1 /******************************************************************************
      2  *
      3  *  Copyright 2003-2012 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /******************************************************************************
     20  *
     21  *  This file implements utility functions for the HeaLth device profile
     22  *  (HL).
     23  *
     24  ******************************************************************************/
     25 
     26 #include <stdio.h>
     27 #include <string.h>
     28 
     29 #include "bt_target.h"
     30 #if (HL_INCLUDED == TRUE)
     31 
     32 #include "bt_common.h"
     33 #include "bta_hl_co.h"
     34 #include "bta_hl_int.h"
     35 #include "mca_api.h"
     36 #include "mca_defs.h"
     37 #include "osi/include/osi.h"
     38 #include "utl.h"
     39 
     40 /*******************************************************************************
     41  *
     42  * Function      bta_hl_set_ctrl_psm_for_dch
     43  *
     44  * Description    This function set the control PSM for the DCH setup
     45  *
     46  * Returns     bool - true - control PSM setting is successful
     47  ******************************************************************************/
     48 bool bta_hl_set_ctrl_psm_for_dch(uint8_t app_idx, uint8_t mcl_idx,
     49                                  UNUSED_ATTR uint8_t mdl_idx,
     50                                  uint16_t ctrl_psm) {
     51   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
     52   bool success = true, update_ctrl_psm = false;
     53 
     54   if (p_mcb->sdp.num_recs) {
     55     if (p_mcb->ctrl_psm != ctrl_psm) {
     56       /* can not use a different ctrl PSM than the current one*/
     57       success = false;
     58     }
     59   } else {
     60     /* No SDP info control i.e. channel was opened by the peer */
     61     update_ctrl_psm = true;
     62   }
     63 
     64   if (success && update_ctrl_psm) {
     65     p_mcb->ctrl_psm = ctrl_psm;
     66   }
     67 
     68 #if (BTA_HL_DEBUG == TRUE)
     69   if (!success) {
     70     APPL_TRACE_DEBUG(
     71         "bta_hl_set_ctrl_psm_for_dch num_recs=%d success=%d update_ctrl_psm=%d "
     72         "ctrl_psm=0x%x ",
     73         p_mcb->sdp.num_recs, success, update_ctrl_psm, ctrl_psm);
     74   }
     75 #endif
     76 
     77   return success;
     78 }
     79 
     80 /*******************************************************************************
     81  *
     82  * Function      bta_hl_find_sdp_idx_using_ctrl_psm
     83  *
     84  * Description
     85  *
     86  * Returns      true if found
     87  *
     88  ******************************************************************************/
     89 bool bta_hl_find_sdp_idx_using_ctrl_psm(tBTA_HL_SDP* p_sdp, uint16_t ctrl_psm,
     90                                         uint8_t* p_sdp_idx) {
     91   bool found = false;
     92   tBTA_HL_SDP_REC* p_rec;
     93   uint8_t i;
     94 
     95   if (ctrl_psm != 0) {
     96     for (i = 0; i < p_sdp->num_recs; i++) {
     97       p_rec = &p_sdp->sdp_rec[i];
     98       if (p_rec->ctrl_psm == ctrl_psm) {
     99         *p_sdp_idx = i;
    100         found = true;
    101         break;
    102       }
    103     }
    104   } else {
    105     *p_sdp_idx = 0;
    106     found = true;
    107   }
    108 
    109 #if (BTA_HL_DEBUG == TRUE)
    110   if (!found) {
    111     APPL_TRACE_DEBUG(
    112         "bta_hl_find_sdp_idx_using_ctrl_psm found=%d sdp_idx=%d ctrl_psm=0x%x ",
    113         found, *p_sdp_idx, ctrl_psm);
    114   }
    115 #endif
    116   return found;
    117 }
    118 
    119 /*******************************************************************************
    120  *
    121  * Function      bta_hl_set_user_tx_buf_size
    122  *
    123  * Description  This function sets the user tx buffer size
    124  *
    125  * Returns      uint16_t buf_size
    126  *
    127  ******************************************************************************/
    128 
    129 uint16_t bta_hl_set_user_tx_buf_size(uint16_t max_tx_size) {
    130   if (max_tx_size > BT_DEFAULT_BUFFER_SIZE) return BTA_HL_LRG_DATA_BUF_SIZE;
    131   return L2CAP_INVALID_ERM_BUF_SIZE;
    132 }
    133 
    134 /*******************************************************************************
    135  *
    136  * Function      bta_hl_set_user_rx_buf_size
    137  *
    138  * Description  This function sets the user rx buffer size
    139  *
    140  * Returns      uint16_t buf_size
    141  *
    142  ******************************************************************************/
    143 
    144 uint16_t bta_hl_set_user_rx_buf_size(uint16_t mtu) {
    145   if (mtu > BT_DEFAULT_BUFFER_SIZE) return BTA_HL_LRG_DATA_BUF_SIZE;
    146   return L2CAP_INVALID_ERM_BUF_SIZE;
    147 }
    148 
    149 /*******************************************************************************
    150  *
    151  * Function      bta_hl_set_tx_win_size
    152  *
    153  * Description  This function sets the tx window size
    154  *
    155  * Returns      uint8_t tx_win_size
    156  *
    157  ******************************************************************************/
    158 uint8_t bta_hl_set_tx_win_size(uint16_t mtu, uint16_t mps) {
    159   uint8_t tx_win_size;
    160 
    161   if (mtu <= mps) {
    162     tx_win_size = 1;
    163   } else {
    164     if (mps > 0) {
    165       tx_win_size = (mtu / mps) + 1;
    166     } else {
    167       APPL_TRACE_ERROR("The MPS is zero");
    168       tx_win_size = 10;
    169     }
    170   }
    171 
    172 #if (BTA_HL_DEBUG == TRUE)
    173   APPL_TRACE_DEBUG("bta_hl_set_tx_win_size win_size=%d mtu=%d mps=%d",
    174                    tx_win_size, mtu, mps);
    175 #endif
    176   return tx_win_size;
    177 }
    178 
    179 /*******************************************************************************
    180  *
    181  * Function      bta_hl_set_mps
    182  *
    183  * Description  This function sets the MPS
    184  *
    185  * Returns      uint16_t MPS
    186  *
    187  ******************************************************************************/
    188 uint16_t bta_hl_set_mps(uint16_t mtu) {
    189   uint16_t mps;
    190   if (mtu > BTA_HL_L2C_MPS) {
    191     mps = BTA_HL_L2C_MPS;
    192   } else {
    193     mps = mtu;
    194   }
    195 #if (BTA_HL_DEBUG == TRUE)
    196   APPL_TRACE_DEBUG("bta_hl_set_mps mps=%d mtu=%d", mps, mtu);
    197 #endif
    198   return mps;
    199 }
    200 
    201 /*******************************************************************************
    202  *
    203  * Function      bta_hl_clean_mdl_cb
    204  *
    205  * Description  This function clean up the specified MDL control block
    206  *
    207  * Returns      void
    208  *
    209  ******************************************************************************/
    210 void bta_hl_clean_mdl_cb(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx) {
    211   tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
    212 #if (BTA_HL_DEBUG == TRUE)
    213   APPL_TRACE_DEBUG("bta_hl_clean_mdl_cb app_idx=%d mcl_idx=%d mdl_idx=%d",
    214                    app_idx, mcl_idx, mdl_idx);
    215 #endif
    216   osi_free_and_reset((void**)&p_dcb->p_tx_pkt);
    217   osi_free_and_reset((void**)&p_dcb->p_rx_pkt);
    218   osi_free_and_reset((void**)&p_dcb->p_echo_tx_pkt);
    219   osi_free_and_reset((void**)&p_dcb->p_echo_rx_pkt);
    220 
    221   memset((void*)p_dcb, 0, sizeof(tBTA_HL_MDL_CB));
    222 }
    223 
    224 /*******************************************************************************
    225  *
    226  * Function      bta_hl_get_buf
    227  *
    228  * Description  This function allocate a buffer based on the specified data size
    229  *
    230  * Returns      BT_HDR *.
    231  *
    232  ******************************************************************************/
    233 BT_HDR* bta_hl_get_buf(uint16_t data_size, bool fcs_use) {
    234   size_t size = data_size + L2CAP_MIN_OFFSET + BT_HDR_SIZE + L2CAP_FCS_LEN +
    235                 L2CAP_EXT_CONTROL_OVERHEAD;
    236 
    237   if (fcs_use) size += L2CAP_FCS_LEN;
    238 
    239   BT_HDR* p_new = (BT_HDR*)osi_malloc(size);
    240   p_new->len = data_size;
    241   p_new->offset = L2CAP_MIN_OFFSET;
    242 
    243   return p_new;
    244 }
    245 
    246 /*******************************************************************************
    247  *
    248  * Function      bta_hl_find_service_in_db
    249  *
    250  * Description  This function check the specified service class(es) can be find
    251  *              in the received SDP database
    252  *
    253  * Returns      bool true - found
    254  *                      false - not found
    255  *
    256  ******************************************************************************/
    257 bool bta_hl_find_service_in_db(uint8_t app_idx, uint8_t mcl_idx,
    258                                uint16_t service_uuid, tSDP_DISC_REC** pp_rec) {
    259   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
    260   bool found = true;
    261 
    262   switch (service_uuid) {
    263     case UUID_SERVCLASS_HDP_SINK:
    264     case UUID_SERVCLASS_HDP_SOURCE:
    265       *pp_rec = SDP_FindServiceInDb(p_mcb->p_db, service_uuid, *pp_rec);
    266       if (*pp_rec == NULL) {
    267         found = false;
    268       }
    269       break;
    270     default:
    271       *pp_rec = bta_hl_find_sink_or_src_srv_class_in_db(p_mcb->p_db, *pp_rec);
    272       if (*pp_rec == NULL) {
    273         found = false;
    274       }
    275       break;
    276   }
    277   return found;
    278 }
    279 
    280 /*******************************************************************************
    281  *
    282  * Function      bta_hl_get_service_uuids
    283  *
    284  *
    285  * Description  This function finds the service class(es) for both CCH and DCH
    286  *              operations
    287  *
    288  * Returns      uint16_t - service_id
    289  *                       if service_uuid = 0xFFFF then it means service uuid
    290  *                       can be either Sink or Source
    291  *
    292  ******************************************************************************/
    293 uint16_t bta_hl_get_service_uuids(uint8_t sdp_oper, uint8_t app_idx,
    294                                   uint8_t mcl_idx, uint8_t mdl_idx) {
    295   tBTA_HL_MDL_CB* p_dcb;
    296   uint16_t service_uuid = 0xFFFF; /* both Sink and Source */
    297 
    298   switch (sdp_oper) {
    299     case BTA_HL_SDP_OP_DCH_OPEN_INIT:
    300     case BTA_HL_SDP_OP_DCH_RECONNECT_INIT:
    301       p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
    302       if (p_dcb->local_mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) {
    303         if (p_dcb->peer_mdep_role == BTA_HL_MDEP_ROLE_SINK) {
    304           service_uuid = UUID_SERVCLASS_HDP_SINK;
    305         } else {
    306           service_uuid = UUID_SERVCLASS_HDP_SOURCE;
    307         }
    308       }
    309       break;
    310     case BTA_HL_SDP_OP_CCH_INIT:
    311     default:
    312       /* use default that is both Sink and Source */
    313       break;
    314   }
    315 #if (BTA_HL_DEBUG == TRUE)
    316   APPL_TRACE_DEBUG("bta_hl_get_service_uuids service_uuid=0x%x", service_uuid);
    317 #endif
    318   return service_uuid;
    319 }
    320 
    321 /*******************************************************************************
    322  *
    323  * Function      bta_hl_find_echo_cfg_rsp
    324  *
    325  *
    326  * Description  This function finds the configuration response for the echo test
    327  *
    328  * Returns      bool - true found
    329  *                        false not found
    330  *
    331  ******************************************************************************/
    332 bool bta_hl_find_echo_cfg_rsp(uint8_t app_idx, uint8_t mcl_idx,
    333                               uint8_t mdep_idx, uint8_t cfg,
    334                               uint8_t* p_cfg_rsp) {
    335   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
    336   tBTA_HL_MDEP* p_mdep = &p_acb->sup_feature.mdep[mdep_idx];
    337   bool status = true;
    338 
    339   if (p_mdep->mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) {
    340     if ((cfg == BTA_HL_DCH_CFG_RELIABLE) || (cfg == BTA_HL_DCH_CFG_STREAMING)) {
    341       *p_cfg_rsp = cfg;
    342     } else if (cfg == BTA_HL_DCH_CFG_NO_PREF) {
    343       *p_cfg_rsp = BTA_HL_DEFAULT_ECHO_TEST_SRC_DCH_CFG;
    344     } else {
    345       status = false;
    346       APPL_TRACE_ERROR("Inavlid echo cfg value");
    347     }
    348     return status;
    349   }
    350 
    351 #if (BTA_HL_DEBUG == TRUE)
    352   if (!status) {
    353     APPL_TRACE_DEBUG(
    354         "bta_hl_find_echo_cfg_rsp status=failed app_idx=%d mcl_idx=%d "
    355         "mdep_idx=%d cfg=%d",
    356         app_idx, mcl_idx, mdep_idx, cfg);
    357   }
    358 #endif
    359 
    360   return status;
    361 }
    362 
    363 /*******************************************************************************
    364  *
    365  * Function      bta_hl_validate_dch_cfg
    366  *
    367  * Description  This function validate the DCH configuration
    368  *
    369  * Returns      bool - true cfg is valid
    370  *                        false not valid
    371  *
    372  ******************************************************************************/
    373 bool bta_hl_validate_cfg(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
    374                          uint8_t cfg) {
    375   tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
    376   bool is_valid = false;
    377 
    378   if (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx) &&
    379       (cfg != BTA_HL_DCH_CFG_RELIABLE)) {
    380     APPL_TRACE_ERROR("the first DCH should be a reliable channel");
    381     return is_valid;
    382   }
    383 
    384   switch (p_dcb->local_cfg) {
    385     case BTA_HL_DCH_CFG_NO_PREF:
    386 
    387       if ((cfg == BTA_HL_DCH_CFG_RELIABLE) ||
    388           (cfg == BTA_HL_DCH_CFG_STREAMING)) {
    389         is_valid = true;
    390       }
    391       break;
    392     case BTA_HL_DCH_CFG_RELIABLE:
    393     case BTA_HL_DCH_CFG_STREAMING:
    394       if (p_dcb->local_cfg == cfg) {
    395         is_valid = true;
    396       }
    397       break;
    398     default:
    399       break;
    400   }
    401 
    402 #if (BTA_HL_DEBUG == TRUE)
    403   if (!is_valid) {
    404     APPL_TRACE_DEBUG("bta_hl_validate_dch_open_cfg is_valid=%d, cfg=%d",
    405                      is_valid, cfg);
    406   }
    407 #endif
    408   return is_valid;
    409 }
    410 
    411 /*******************************************************************************
    412  *
    413  * Function       bta_hl_find_cch_cb_indexes
    414  *
    415  * Description  This function finds the indexes needed for the CCH state machine
    416  *
    417  * Returns      bool - true found
    418  *                        false not found
    419  *
    420  ******************************************************************************/
    421 bool bta_hl_find_cch_cb_indexes(tBTA_HL_DATA* p_msg, uint8_t* p_app_idx,
    422                                 uint8_t* p_mcl_idx) {
    423   bool found = false;
    424   tBTA_HL_MCL_CB* p_mcb;
    425   uint8_t app_idx = 0, mcl_idx = 0;
    426 
    427   switch (p_msg->hdr.event) {
    428     case BTA_HL_CCH_SDP_OK_EVT:
    429     case BTA_HL_CCH_SDP_FAIL_EVT:
    430       app_idx = p_msg->cch_sdp.app_idx;
    431       mcl_idx = p_msg->cch_sdp.mcl_idx;
    432       found = true;
    433       break;
    434 
    435     case BTA_HL_MCA_CONNECT_IND_EVT:
    436 
    437       if (bta_hl_find_app_idx_using_handle(p_msg->mca_evt.app_handle,
    438                                            &app_idx)) {
    439         if (bta_hl_find_mcl_idx(app_idx,
    440                                 p_msg->mca_evt.mca_data.connect_ind.bd_addr,
    441                                 &mcl_idx)) {
    442           /* local initiated */
    443           found = true;
    444         } else if (!bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle,
    445                                                      &app_idx, &mcl_idx) &&
    446                    bta_hl_find_avail_mcl_idx(app_idx, &mcl_idx)) {
    447           /* remote initiated */
    448           p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
    449           p_mcb->in_use = true;
    450           p_mcb->cch_oper = BTA_HL_CCH_OP_REMOTE_OPEN;
    451           found = true;
    452         }
    453       }
    454       break;
    455 
    456     case BTA_HL_MCA_DISCONNECT_IND_EVT:
    457 
    458       if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
    459                                            &mcl_idx)) {
    460         found = true;
    461       } else if (bta_hl_find_app_idx_using_handle(p_msg->mca_evt.app_handle,
    462                                                   &app_idx) &&
    463                  bta_hl_find_mcl_idx(
    464                      app_idx, p_msg->mca_evt.mca_data.disconnect_ind.bd_addr,
    465                      &mcl_idx)) {
    466         found = true;
    467       }
    468 
    469       if (found) {
    470         p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
    471         if ((p_mcb->cch_oper != BTA_HL_CCH_OP_LOCAL_CLOSE) &&
    472             (p_mcb->cch_oper != BTA_HL_CCH_OP_LOCAL_OPEN)) {
    473           p_mcb->cch_oper = BTA_HL_CCH_OP_REMOTE_CLOSE;
    474         }
    475       }
    476       break;
    477 
    478     case BTA_HL_MCA_RSP_TOUT_IND_EVT:
    479 
    480       if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
    481                                            &mcl_idx)) {
    482         found = true;
    483       }
    484 
    485       if (found) {
    486         p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
    487         if ((p_mcb->cch_oper != BTA_HL_CCH_OP_REMOTE_CLOSE) &&
    488             (p_mcb->cch_oper != BTA_HL_CCH_OP_LOCAL_OPEN)) {
    489           p_mcb->cch_oper = BTA_HL_CCH_OP_LOCAL_CLOSE;
    490         }
    491       }
    492       break;
    493     default:
    494       break;
    495   }
    496 
    497   if (found) {
    498     *p_app_idx = app_idx;
    499     *p_mcl_idx = mcl_idx;
    500   }
    501 
    502 #if (BTA_HL_DEBUG == TRUE)
    503   if (!found) {
    504     APPL_TRACE_DEBUG(
    505         "bta_hl_find_cch_cb_indexes event=%s found=%d app_idx=%d mcl_idx=%d",
    506         bta_hl_evt_code(p_msg->hdr.event), found, app_idx, mcl_idx);
    507   }
    508 #endif
    509 
    510   return found;
    511 }
    512 
    513 /*******************************************************************************
    514  *
    515  * Function       bta_hl_find_dch_cb_indexes
    516  *
    517  * Description  This function finds the indexes needed for the DCH state machine
    518  *
    519  * Returns      bool - true found
    520  *                        false not found
    521  *
    522  ******************************************************************************/
    523 bool bta_hl_find_dch_cb_indexes(tBTA_HL_DATA* p_msg, uint8_t* p_app_idx,
    524                                 uint8_t* p_mcl_idx, uint8_t* p_mdl_idx) {
    525   bool found = false;
    526   tBTA_HL_MCL_CB* p_mcb;
    527   uint8_t app_idx = 0, mcl_idx = 0, mdl_idx = 0;
    528 
    529   switch (p_msg->hdr.event) {
    530     case BTA_HL_MCA_CREATE_CFM_EVT:
    531       if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
    532                                            &mcl_idx) &&
    533           bta_hl_find_mdl_idx(app_idx, mcl_idx,
    534                               p_msg->mca_evt.mca_data.create_cfm.mdl_id,
    535                               &mdl_idx)) {
    536         found = true;
    537       }
    538       break;
    539 
    540     case BTA_HL_MCA_CREATE_IND_EVT:
    541     case BTA_HL_MCA_RECONNECT_IND_EVT:
    542       if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
    543                                            &mcl_idx) &&
    544           bta_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx)) {
    545         found = true;
    546       }
    547       break;
    548 
    549     case BTA_HL_MCA_OPEN_CFM_EVT:
    550       if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
    551                                            &mcl_idx) &&
    552           bta_hl_find_mdl_idx(app_idx, mcl_idx,
    553                               p_msg->mca_evt.mca_data.open_cfm.mdl_id,
    554                               &mdl_idx)) {
    555         found = true;
    556       }
    557       break;
    558 
    559     case BTA_HL_MCA_OPEN_IND_EVT:
    560       if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
    561                                            &mcl_idx) &&
    562           bta_hl_find_mdl_idx(app_idx, mcl_idx,
    563                               p_msg->mca_evt.mca_data.open_ind.mdl_id,
    564                               &mdl_idx)) {
    565         found = true;
    566       }
    567       break;
    568 
    569     case BTA_HL_MCA_CLOSE_CFM_EVT:
    570 
    571       if (bta_hl_find_mdl_idx_using_handle(
    572               (tBTA_HL_MDL_HANDLE)p_msg->mca_evt.mca_data.close_cfm.mdl,
    573               &app_idx, &mcl_idx, &mdl_idx)) {
    574         found = true;
    575       }
    576       break;
    577     case BTA_HL_MCA_CLOSE_IND_EVT:
    578 
    579       if (bta_hl_find_mdl_idx_using_handle(
    580               (tBTA_HL_MDL_HANDLE)p_msg->mca_evt.mca_data.close_ind.mdl,
    581               &app_idx, &mcl_idx, &mdl_idx)) {
    582         found = true;
    583       }
    584       break;
    585     case BTA_HL_API_SEND_DATA_EVT:
    586 
    587       if (bta_hl_find_mdl_idx_using_handle(p_msg->api_send_data.mdl_handle,
    588                                            &app_idx, &mcl_idx, &mdl_idx)) {
    589         found = true;
    590       }
    591 
    592       break;
    593 
    594     case BTA_HL_MCA_CONG_CHG_EVT:
    595 
    596       if (bta_hl_find_mdl_idx_using_handle(
    597               (tBTA_HL_MDL_HANDLE)p_msg->mca_evt.mca_data.cong_chg.mdl,
    598               &app_idx, &mcl_idx, &mdl_idx)) {
    599         found = true;
    600       }
    601 
    602       break;
    603 
    604     case BTA_HL_MCA_RCV_DATA_EVT:
    605       app_idx = p_msg->mca_rcv_data_evt.app_idx;
    606       mcl_idx = p_msg->mca_rcv_data_evt.mcl_idx;
    607       mdl_idx = p_msg->mca_rcv_data_evt.mdl_idx;
    608       found = true;
    609       break;
    610     case BTA_HL_DCH_RECONNECT_EVT:
    611     case BTA_HL_DCH_OPEN_EVT:
    612     case BTA_HL_DCH_ECHO_TEST_EVT:
    613     case BTA_HL_DCH_SDP_FAIL_EVT:
    614       app_idx = p_msg->dch_sdp.app_idx;
    615       mcl_idx = p_msg->dch_sdp.mcl_idx;
    616       mdl_idx = p_msg->dch_sdp.mdl_idx;
    617       found = true;
    618       break;
    619     case BTA_HL_MCA_RECONNECT_CFM_EVT:
    620       if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
    621                                            &mcl_idx) &&
    622           bta_hl_find_mdl_idx(app_idx, mcl_idx,
    623                               p_msg->mca_evt.mca_data.reconnect_cfm.mdl_id,
    624                               &mdl_idx)) {
    625         found = true;
    626       }
    627       break;
    628 
    629     case BTA_HL_API_DCH_CREATE_RSP_EVT:
    630       if (bta_hl_find_mcl_idx_using_handle(p_msg->api_dch_create_rsp.mcl_handle,
    631                                            &app_idx, &mcl_idx) &&
    632           bta_hl_find_mdl_idx(app_idx, mcl_idx,
    633                               p_msg->api_dch_create_rsp.mdl_id, &mdl_idx)) {
    634         found = true;
    635       }
    636       break;
    637     case BTA_HL_MCA_ABORT_IND_EVT:
    638       if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
    639                                            &mcl_idx) &&
    640           bta_hl_find_mdl_idx(app_idx, mcl_idx,
    641                               p_msg->mca_evt.mca_data.abort_ind.mdl_id,
    642                               &mdl_idx)) {
    643         found = true;
    644       }
    645       break;
    646     case BTA_HL_MCA_ABORT_CFM_EVT:
    647       if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
    648                                            &mcl_idx) &&
    649           bta_hl_find_mdl_idx(app_idx, mcl_idx,
    650                               p_msg->mca_evt.mca_data.abort_cfm.mdl_id,
    651                               &mdl_idx)) {
    652         found = true;
    653       }
    654       break;
    655     case BTA_HL_CI_GET_TX_DATA_EVT:
    656     case BTA_HL_CI_PUT_RX_DATA_EVT:
    657       if (bta_hl_find_mdl_idx_using_handle(p_msg->ci_get_put_data.mdl_handle,
    658                                            &app_idx, &mcl_idx, &mdl_idx)) {
    659         found = true;
    660       }
    661       break;
    662     case BTA_HL_CI_GET_ECHO_DATA_EVT:
    663     case BTA_HL_CI_PUT_ECHO_DATA_EVT:
    664       if (bta_hl_find_mcl_idx_using_handle(
    665               p_msg->ci_get_put_echo_data.mcl_handle, &app_idx, &mcl_idx)) {
    666         p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
    667         mdl_idx = p_mcb->echo_mdl_idx;
    668         found = true;
    669       }
    670       break;
    671 
    672     default:
    673       break;
    674   }
    675 
    676   if (found) {
    677     *p_app_idx = app_idx;
    678     *p_mcl_idx = mcl_idx;
    679     *p_mdl_idx = mdl_idx;
    680   }
    681 #if (BTA_HL_DEBUG == TRUE)
    682   if (!found) {
    683     APPL_TRACE_DEBUG(
    684         "bta_hl_find_dch_cb_indexes event=%s found=%d app_idx=%d mcl_idx=%d "
    685         "mdl_idx=%d",
    686         bta_hl_evt_code(p_msg->hdr.event), found, *p_app_idx, *p_mcl_idx,
    687         *p_mdl_idx);
    688   }
    689 #endif
    690 
    691   return found;
    692 }
    693 
    694 /*******************************************************************************
    695  *
    696  * Function      bta_hl_allocate_mdl_id
    697  *
    698  * Description  This function allocates a MDL ID
    699  *
    700  * Returns      uint16_t - MDL ID
    701  *
    702  ******************************************************************************/
    703 uint16_t bta_hl_allocate_mdl_id(uint8_t app_idx, uint8_t mcl_idx,
    704                                 uint8_t mdl_idx) {
    705   uint16_t mdl_id = 0;
    706   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
    707   bool duplicate_id;
    708   uint8_t i, mdl_cfg_idx;
    709 
    710   do {
    711     duplicate_id = false;
    712     mdl_id = ((mdl_id + 1) & 0xFEFF);
    713     /* check mdl_ids that are used for the current conenctions */
    714     for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
    715       if (p_mcb->mdl[i].in_use && (i != mdl_idx) &&
    716           (p_mcb->mdl[i].mdl_id == mdl_id)) {
    717         duplicate_id = true;
    718         break;
    719       }
    720     }
    721 
    722     if (duplicate_id) {
    723       /* start from the beginning to get another MDL value*/
    724       continue;
    725     } else {
    726       /* check mdl_ids that are stored in the persistent memory */
    727       if (bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, mdl_id, &mdl_cfg_idx)) {
    728         duplicate_id = true;
    729       } else {
    730         /* found a new MDL value */
    731         break;
    732       }
    733     }
    734 
    735   } while (true);
    736 
    737 #if (BTA_HL_DEBUG == TRUE)
    738   APPL_TRACE_DEBUG("bta_hl_allocate_mdl OK mdl_id=%d", mdl_id);
    739 #endif
    740   return mdl_id;
    741 }
    742 /*******************************************************************************
    743  *
    744  * Function      bta_hl_find_mdl_idx
    745  *
    746  * Description  This function finds the MDL index based on mdl_id
    747  *
    748  * Returns      bool true-found
    749  *
    750  ******************************************************************************/
    751 bool bta_hl_find_mdl_idx(uint8_t app_idx, uint8_t mcl_idx, uint16_t mdl_id,
    752                          uint8_t* p_mdl_idx) {
    753   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
    754   bool found = false;
    755   uint8_t i;
    756 
    757   for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
    758     if (p_mcb->mdl[i].in_use && (mdl_id != 0) &&
    759         (p_mcb->mdl[i].mdl_id == mdl_id)) {
    760       found = true;
    761       *p_mdl_idx = i;
    762       break;
    763     }
    764   }
    765 
    766 #if (BTA_HL_DEBUG == TRUE)
    767   if (!found) {
    768     APPL_TRACE_DEBUG("bta_hl_find_mdl_idx found=%d mdl_id=%d mdl_idx=%d ",
    769                      found, mdl_id, i);
    770   }
    771 #endif
    772 
    773   return found;
    774 }
    775 
    776 /*******************************************************************************
    777  *
    778  * Function      bta_hl_find_an_active_mdl_idx
    779  *
    780  * Description  This function finds an active MDL
    781  *
    782  * Returns      bool true-found
    783  *
    784  ******************************************************************************/
    785 bool bta_hl_find_an_active_mdl_idx(uint8_t app_idx, uint8_t mcl_idx,
    786                                    uint8_t* p_mdl_idx) {
    787   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
    788   bool found = false;
    789   uint8_t i;
    790 
    791   for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
    792     if (p_mcb->mdl[i].in_use &&
    793         (p_mcb->mdl[i].dch_state == BTA_HL_DCH_OPEN_ST)) {
    794       found = true;
    795       *p_mdl_idx = i;
    796       break;
    797     }
    798   }
    799 
    800 #if (BTA_HL_DEBUG == TRUE)
    801   if (found) {
    802     APPL_TRACE_DEBUG(
    803         "bta_hl_find_an_opened_mdl_idx found=%d app_idx=%d mcl_idx=%d "
    804         "mdl_idx=%d",
    805         found, app_idx, mcl_idx, i);
    806   }
    807 #endif
    808 
    809   return found;
    810 }
    811 
    812 /*******************************************************************************
    813  *
    814  * Function      bta_hl_find_dch_setup_mdl_idx
    815  *
    816  * Description  This function finds a MDL which in the DCH setup state
    817  *
    818  * Returns      bool true-found
    819  *
    820  ******************************************************************************/
    821 bool bta_hl_find_dch_setup_mdl_idx(uint8_t app_idx, uint8_t mcl_idx,
    822                                    uint8_t* p_mdl_idx) {
    823   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
    824   bool found = false;
    825   uint8_t i;
    826 
    827   for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
    828     if (p_mcb->mdl[i].in_use &&
    829         (p_mcb->mdl[i].dch_state == BTA_HL_DCH_OPENING_ST)) {
    830       found = true;
    831       *p_mdl_idx = i;
    832       break;
    833     }
    834   }
    835 
    836 #if (BTA_HL_DEBUG == TRUE)
    837   if (found) {
    838     APPL_TRACE_DEBUG(
    839         "bta_hl_find_dch_setup_mdl_idx found=%d app_idx=%d mcl_idx=%d "
    840         "mdl_idx=%d",
    841         found, app_idx, mcl_idx, i);
    842   }
    843 #endif
    844 
    845   return found;
    846 }
    847 
    848 /*******************************************************************************
    849  *
    850  * Function      bta_hl_find_an_in_use_mcl_idx
    851  *
    852  * Description  This function finds an in-use MCL control block index
    853  *
    854  * Returns      bool true-found
    855  *
    856  ******************************************************************************/
    857 bool bta_hl_find_an_in_use_mcl_idx(uint8_t app_idx, uint8_t* p_mcl_idx) {
    858   tBTA_HL_MCL_CB* p_mcb;
    859   bool found = false;
    860   uint8_t i;
    861 
    862   for (i = 0; i < BTA_HL_NUM_MCLS; i++) {
    863     p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, i);
    864     if (p_mcb->in_use && (p_mcb->cch_state != BTA_HL_CCH_IDLE_ST)) {
    865       found = true;
    866       *p_mcl_idx = i;
    867       break;
    868     }
    869   }
    870 
    871 #if (BTA_HL_DEBUG == TRUE)
    872   if (found) {
    873     APPL_TRACE_DEBUG(
    874         "bta_hl_find_an_in_use_mcl_idx found=%d app_idx=%d mcl_idx=%d ", found,
    875         app_idx, i);
    876   }
    877 #endif
    878 
    879   return found;
    880 }
    881 
    882 /*******************************************************************************
    883  *
    884  * Function      bta_hl_find_an_in_use_app_idx
    885  *
    886  * Description  This function finds an in-use application control block index
    887  *
    888  * Returns      bool true-found
    889  *
    890  ******************************************************************************/
    891 bool bta_hl_find_an_in_use_app_idx(uint8_t* p_app_idx) {
    892   tBTA_HL_APP_CB* p_acb;
    893   bool found = false;
    894   uint8_t i;
    895 
    896   for (i = 0; i < BTA_HL_NUM_APPS; i++) {
    897     p_acb = BTA_HL_GET_APP_CB_PTR(i);
    898     if (p_acb->in_use) {
    899       found = true;
    900       *p_app_idx = i;
    901       break;
    902     }
    903   }
    904 
    905 #if (BTA_HL_DEBUG == TRUE)
    906   if (found) {
    907     APPL_TRACE_DEBUG("bta_hl_find_an_in_use_app_idx found=%d app_idx=%d ",
    908                      found, i);
    909   }
    910 #endif
    911 
    912   return found;
    913 }
    914 /*******************************************************************************
    915  *
    916  * Function      bta_hl_find_app_idx
    917  *
    918  * Description  This function finds the application control block index based on
    919  *              the application ID
    920  *
    921  * Returns      bool true-found
    922  *
    923  ******************************************************************************/
    924 bool bta_hl_find_app_idx(uint8_t app_id, uint8_t* p_app_idx) {
    925   bool found = false;
    926   uint8_t i;
    927 
    928   for (i = 0; i < BTA_HL_NUM_APPS; i++) {
    929     if (bta_hl_cb.acb[i].in_use && (bta_hl_cb.acb[i].app_id == app_id)) {
    930       found = true;
    931       *p_app_idx = i;
    932       break;
    933     }
    934   }
    935 
    936 #if (BTA_HL_DEBUG == TRUE)
    937   APPL_TRACE_DEBUG("bta_hl_find_app_idx found=%d app_id=%d idx=%d ", found,
    938                    app_id, i);
    939 #endif
    940 
    941   return found;
    942 }
    943 
    944 /*******************************************************************************
    945  *
    946  * Function      bta_hl_find_app_idx_using_handle
    947  *
    948  * Description  This function finds the application control block index based on
    949  *              the application handle
    950  *
    951  * Returns      bool true-found
    952  *
    953  ******************************************************************************/
    954 bool bta_hl_find_app_idx_using_handle(tBTA_HL_APP_HANDLE app_handle,
    955                                       uint8_t* p_app_idx) {
    956   bool found = false;
    957   uint8_t i;
    958 
    959   for (i = 0; i < BTA_HL_NUM_APPS; i++) {
    960     if (bta_hl_cb.acb[i].in_use &&
    961         (bta_hl_cb.acb[i].app_handle == app_handle)) {
    962       found = true;
    963       *p_app_idx = i;
    964       break;
    965     }
    966   }
    967 
    968 #if (BTA_HL_DEBUG == TRUE)
    969   if (!found) {
    970     APPL_TRACE_DEBUG(
    971         "bta_hl_find_app_idx_using_mca_handle status=%d handle=%d app_idx=%d ",
    972         found, app_handle, i);
    973   }
    974 #endif
    975 
    976   return found;
    977 }
    978 
    979 /*******************************************************************************
    980  *
    981  * Function      bta_hl_find_mcl_idx_using_handle
    982  *
    983  * Description  This function finds the MCL control block index based on
    984  *              the MCL handle
    985  *
    986  * Returns      bool true-found
    987  *
    988  ******************************************************************************/
    989 bool bta_hl_find_mcl_idx_using_handle(tBTA_HL_MCL_HANDLE mcl_handle,
    990                                       uint8_t* p_app_idx, uint8_t* p_mcl_idx) {
    991   tBTA_HL_APP_CB* p_acb;
    992   bool found = false;
    993   uint8_t i = 0, j = 0;
    994 
    995   for (i = 0; i < BTA_HL_NUM_APPS; i++) {
    996     p_acb = BTA_HL_GET_APP_CB_PTR(i);
    997     if (p_acb->in_use) {
    998       for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
    999         if (p_acb->mcb[j].mcl_handle == mcl_handle) {
   1000           found = true;
   1001           *p_app_idx = i;
   1002           *p_mcl_idx = j;
   1003           break;
   1004         }
   1005       }
   1006     }
   1007   }
   1008 
   1009 #if (BTA_HL_DEBUG == TRUE)
   1010   if (!found) {
   1011     APPL_TRACE_DEBUG(
   1012         "bta_hl_find_mcl_idx_using_handle found=%d app_idx=%d mcl_idx=%d",
   1013         found, i, j);
   1014   }
   1015 #endif
   1016   return found;
   1017 }
   1018 
   1019 /*******************************************************************************
   1020  *
   1021  * Function      bta_hl_find_mcl_idx
   1022  *
   1023  * Description  This function finds the MCL control block index based on
   1024  *              the peer BD address
   1025  *
   1026  * Returns      bool true-found
   1027  *
   1028  ******************************************************************************/
   1029 bool bta_hl_find_mcl_idx(uint8_t app_idx, const RawAddress& p_bd_addr,
   1030                          uint8_t* p_mcl_idx) {
   1031   bool found = false;
   1032   uint8_t i;
   1033 
   1034   for (i = 0; i < BTA_HL_NUM_MCLS; i++) {
   1035     if (bta_hl_cb.acb[app_idx].mcb[i].in_use &&
   1036         bta_hl_cb.acb[app_idx].mcb[i].bd_addr == p_bd_addr) {
   1037       found = true;
   1038       *p_mcl_idx = i;
   1039       break;
   1040     }
   1041   }
   1042 
   1043 #if (BTA_HL_DEBUG == TRUE)
   1044   if (!found) {
   1045     APPL_TRACE_DEBUG("bta_hl_find_mcl_idx found=%d idx=%d", found, i);
   1046   }
   1047 #endif
   1048   return found;
   1049 }
   1050 
   1051 /*******************************************************************************
   1052  *
   1053  * Function      bta_hl_find_mdl_idx_using_handle
   1054  *
   1055  * Description  This function finds the MDL control block index based on
   1056  *              the MDL handle
   1057  *
   1058  * Returns      bool true-found
   1059  *
   1060  ******************************************************************************/
   1061 bool bta_hl_find_mdl_idx_using_handle(tBTA_HL_MDL_HANDLE mdl_handle,
   1062                                       uint8_t* p_app_idx, uint8_t* p_mcl_idx,
   1063                                       uint8_t* p_mdl_idx) {
   1064   tBTA_HL_APP_CB* p_acb;
   1065   tBTA_HL_MCL_CB* p_mcb;
   1066   tBTA_HL_MDL_CB* p_dcb;
   1067   bool found = false;
   1068   uint8_t i, j, k;
   1069 
   1070   for (i = 0; i < BTA_HL_NUM_APPS; i++) {
   1071     p_acb = BTA_HL_GET_APP_CB_PTR(i);
   1072     if (p_acb->in_use) {
   1073       for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
   1074         p_mcb = BTA_HL_GET_MCL_CB_PTR(i, j);
   1075         if (p_mcb->in_use) {
   1076           for (k = 0; k < BTA_HL_NUM_MDLS_PER_MCL; k++) {
   1077             p_dcb = BTA_HL_GET_MDL_CB_PTR(i, j, k);
   1078             if (p_dcb->in_use) {
   1079               if (p_dcb->mdl_handle == mdl_handle) {
   1080                 found = true;
   1081                 *p_app_idx = i;
   1082                 *p_mcl_idx = j;
   1083                 *p_mdl_idx = k;
   1084                 break;
   1085               }
   1086             }
   1087           }
   1088         }
   1089       }
   1090     }
   1091   }
   1092 
   1093 #if (BTA_HL_DEBUG == TRUE)
   1094   if (!found) {
   1095     APPL_TRACE_DEBUG(
   1096         "bta_hl_find_mdl_idx_using_handle found=%d mdl_handle=%d  ", found,
   1097         mdl_handle);
   1098   }
   1099 #endif
   1100   return found;
   1101 }
   1102 /*******************************************************************************
   1103  *
   1104  * Function      bta_hl_is_the_first_reliable_existed
   1105  *
   1106  * Description  This function checks whether the first reliable DCH channel
   1107  *              has been setup on the MCL or not
   1108  *
   1109  * Returns      bool - true exist
   1110  *                        false does not exist
   1111  *
   1112  ******************************************************************************/
   1113 bool bta_hl_is_the_first_reliable_existed(uint8_t app_idx, uint8_t mcl_idx) {
   1114   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
   1115   bool is_existed = false;
   1116   uint8_t i;
   1117 
   1118   for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
   1119     if (p_mcb->mdl[i].in_use && p_mcb->mdl[i].is_the_first_reliable) {
   1120       is_existed = true;
   1121       break;
   1122     }
   1123   }
   1124 
   1125 #if (BTA_HL_DEBUG == TRUE)
   1126   APPL_TRACE_DEBUG("bta_hl_is_the_first_reliable_existed is_existed=%d  ",
   1127                    is_existed);
   1128 #endif
   1129   return is_existed;
   1130 }
   1131 
   1132 /*******************************************************************************
   1133  *
   1134  * Function      bta_hl_find_non_active_mdl_cfg
   1135  *
   1136  * Description  This function finds a valid MDL configiration index and this
   1137  *              MDL ID is not active
   1138  *
   1139  * Returns      bool - true found
   1140  *                        false not found
   1141  *
   1142  ******************************************************************************/
   1143 bool bta_hl_find_non_active_mdl_cfg(uint8_t app_idx, uint8_t start_mdl_cfg_idx,
   1144                                     uint8_t* p_mdl_cfg_idx) {
   1145   tBTA_HL_MCL_CB* p_mcb;
   1146   tBTA_HL_MDL_CB* p_dcb;
   1147   tBTA_HL_MDL_CFG* p_mdl;
   1148   bool mdl_in_use;
   1149   bool found = false;
   1150   uint8_t i, j, k;
   1151 
   1152   for (i = start_mdl_cfg_idx; i < BTA_HL_NUM_MDL_CFGS; i++) {
   1153     mdl_in_use = false;
   1154     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
   1155     for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
   1156       p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, j);
   1157       if (p_mcb->in_use && p_mdl->peer_bd_addr == p_mcb->bd_addr) {
   1158         for (k = 0; k < BTA_HL_NUM_MDLS_PER_MCL; k++) {
   1159           p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, j, k);
   1160 
   1161           if (p_dcb->in_use && p_mdl->mdl_id == p_dcb->mdl_id) {
   1162             mdl_in_use = true;
   1163             break;
   1164           }
   1165         }
   1166       }
   1167 
   1168       if (mdl_in_use) {
   1169         break;
   1170       }
   1171     }
   1172 
   1173     if (!mdl_in_use) {
   1174       *p_mdl_cfg_idx = i;
   1175       found = true;
   1176       break;
   1177     }
   1178   }
   1179 
   1180   return found;
   1181 }
   1182 
   1183 /*******************************************************************************
   1184  *
   1185  * Function      bta_hl_find_mdl_cfg_idx
   1186  *
   1187  * Description  This function finds an available MDL configuration index
   1188  *
   1189  * Returns      bool - true found
   1190  *                        false not found
   1191  *
   1192  ******************************************************************************/
   1193 bool bta_hl_find_avail_mdl_cfg_idx(uint8_t app_idx, UNUSED_ATTR uint8_t mcl_idx,
   1194                                    uint8_t* p_mdl_cfg_idx) {
   1195   tBTA_HL_MDL_CFG *p_mdl, *p_mdl1, *p_mdl2;
   1196   uint8_t i;
   1197   bool found = false;
   1198   uint8_t first_mdl_cfg_idx, second_mdl_cfg_idx, older_mdl_cfg_idx;
   1199   bool done;
   1200 
   1201   for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
   1202     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
   1203     if (!p_mdl->active) {
   1204       /* found an unused space to store mdl cfg*/
   1205       found = true;
   1206       *p_mdl_cfg_idx = i;
   1207       break;
   1208     }
   1209   }
   1210 
   1211   if (!found) {
   1212     /* all available mdl cfg spaces are in use so we need to find the mdl cfg
   1213     which is
   1214     not currently in use and has the the oldest time stamp to remove*/
   1215 
   1216     found = true;
   1217     if (bta_hl_find_non_active_mdl_cfg(app_idx, 0, &first_mdl_cfg_idx)) {
   1218       if (bta_hl_find_non_active_mdl_cfg(
   1219               app_idx, (uint8_t)(first_mdl_cfg_idx + 1), &second_mdl_cfg_idx)) {
   1220         done = false;
   1221         while (!done) {
   1222           p_mdl1 = BTA_HL_GET_MDL_CFG_PTR(app_idx, first_mdl_cfg_idx);
   1223           p_mdl2 = BTA_HL_GET_MDL_CFG_PTR(app_idx, second_mdl_cfg_idx);
   1224 
   1225           if (p_mdl1->time < p_mdl2->time) {
   1226             older_mdl_cfg_idx = first_mdl_cfg_idx;
   1227           } else {
   1228             older_mdl_cfg_idx = second_mdl_cfg_idx;
   1229           }
   1230 
   1231           if (bta_hl_find_non_active_mdl_cfg(app_idx,
   1232                                              (uint8_t)(second_mdl_cfg_idx + 1),
   1233                                              &second_mdl_cfg_idx)) {
   1234             first_mdl_cfg_idx = older_mdl_cfg_idx;
   1235           } else {
   1236             done = true;
   1237           }
   1238         }
   1239 
   1240         *p_mdl_cfg_idx = older_mdl_cfg_idx;
   1241 
   1242       } else {
   1243         *p_mdl_cfg_idx = first_mdl_cfg_idx;
   1244       }
   1245 
   1246     } else {
   1247       found = false;
   1248     }
   1249   }
   1250 
   1251 #if (BTA_HL_DEBUG == TRUE)
   1252   if (!found) {
   1253     APPL_TRACE_DEBUG("bta_hl_find_avail_mdl_cfg_idx found=%d mdl_cfg_idx=%d ",
   1254                      found, *p_mdl_cfg_idx);
   1255   }
   1256 #endif
   1257 
   1258   return found;
   1259 }
   1260 
   1261 /*******************************************************************************
   1262  *
   1263  * Function      bta_hl_find_mdl_cfg_idx
   1264  *
   1265  * Description  This function finds the MDL configuration index based on
   1266  *              the MDL ID
   1267  *
   1268  * Returns      bool - true found
   1269  *                        false not found
   1270  *
   1271  ******************************************************************************/
   1272 bool bta_hl_find_mdl_cfg_idx(uint8_t app_idx, uint8_t mcl_idx,
   1273                              tBTA_HL_MDL_ID mdl_id, uint8_t* p_mdl_cfg_idx) {
   1274   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
   1275   tBTA_HL_MDL_CFG* p_mdl;
   1276   uint8_t i;
   1277   bool found = false;
   1278 
   1279   *p_mdl_cfg_idx = 0;
   1280   for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
   1281     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
   1282     if (p_mdl->active)
   1283       APPL_TRACE_DEBUG("bta_hl_find_mdl_cfg_idx: mdl_id =%d, p_mdl->mdl_id=%d",
   1284                        mdl_id, p_mdl->mdl_id);
   1285     if (p_mdl->active && p_mcb->bd_addr == p_mdl->peer_bd_addr &&
   1286         (p_mdl->mdl_id == mdl_id)) {
   1287       found = true;
   1288       *p_mdl_cfg_idx = i;
   1289       break;
   1290     }
   1291   }
   1292 
   1293 #if (BTA_HL_DEBUG == TRUE)
   1294   if (!found) {
   1295     APPL_TRACE_DEBUG("bta_hl_find_mdl_cfg_idx found=%d mdl_cfg_idx=%d ", found,
   1296                      i);
   1297   }
   1298 #endif
   1299 
   1300   return found;
   1301 }
   1302 
   1303 /*******************************************************************************
   1304  *
   1305  * Function      bta_hl_get_cur_time
   1306  *
   1307  * Description  This function get the cuurent time value
   1308  *
   1309  * Returns      bool - true found
   1310  *                        false not found
   1311  *
   1312  ******************************************************************************/
   1313 bool bta_hl_get_cur_time(uint8_t app_idx, uint8_t* p_cur_time) {
   1314   tBTA_HL_MDL_CFG* p_mdl;
   1315   uint8_t i, j, time_latest, time;
   1316   bool found = false, result = true;
   1317 
   1318   for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
   1319     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
   1320     if (p_mdl->active) {
   1321       found = true;
   1322       time_latest = p_mdl->time;
   1323       for (j = (i + 1); j < BTA_HL_NUM_MDL_CFGS; j++) {
   1324         p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, j);
   1325         if (p_mdl->active) {
   1326           time = p_mdl->time;
   1327           if (time > time_latest) {
   1328             time_latest = time;
   1329           }
   1330         }
   1331       }
   1332       break;
   1333     }
   1334   }
   1335 
   1336   if (found) {
   1337     if (time_latest < BTA_HL_MAX_TIME) {
   1338       *p_cur_time = time_latest + 1;
   1339     } else {
   1340       /* need to wrap around */
   1341       result = false;
   1342     }
   1343   } else {
   1344     *p_cur_time = BTA_HL_MIN_TIME;
   1345   }
   1346 
   1347 #if (BTA_HL_DEBUG == TRUE)
   1348   if (!result) {
   1349     APPL_TRACE_DEBUG("bta_hl_get_cur_time result=%s cur_time=%d",
   1350                      (result ? "OK" : "FAIL"), *p_cur_time);
   1351   }
   1352 #endif
   1353 
   1354   return result;
   1355 }
   1356 
   1357 /*******************************************************************************
   1358  *
   1359  * Function      bta_hl_sort_cfg_time_idx
   1360  *
   1361  * Description  This function sort the mdl configuration idx stored in array a
   1362  *              based on decending time value
   1363  *
   1364  * Returns      bool - true found
   1365  *                        false not found
   1366  *
   1367  ******************************************************************************/
   1368 void bta_hl_sort_cfg_time_idx(uint8_t app_idx, uint8_t* a, uint8_t n) {
   1369   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   1370   uint8_t temp_time, temp_idx;
   1371   int16_t i, j;
   1372   for (i = 1; i < n; ++i) {
   1373     temp_idx = a[i];
   1374     temp_time = p_acb->mdl_cfg[temp_idx].time;
   1375     j = i - 1;
   1376     while ((j >= 0) && (temp_time < p_acb->mdl_cfg[a[j]].time)) {
   1377       a[j + 1] = a[j];
   1378       --j;
   1379     }
   1380     a[j + 1] = temp_idx;
   1381   }
   1382 }
   1383 
   1384 /*******************************************************************************
   1385  *
   1386  * Function      bta_hl_compact_mdl_cfg_time
   1387  *
   1388  * Description  This function finds the MDL configuration index based on
   1389  *              the MDL ID
   1390  *
   1391  * Returns      bool - true found
   1392  *                        false not found
   1393  *
   1394  ******************************************************************************/
   1395 void bta_hl_compact_mdl_cfg_time(uint8_t app_idx, uint8_t mdep_id) {
   1396   tBTA_HL_MDL_CFG* p_mdl;
   1397   uint8_t i, time_min, cnt = 0;
   1398   uint8_t s_arr[BTA_HL_NUM_MDL_CFGS];
   1399 
   1400   for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
   1401     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
   1402     if (p_mdl->active) {
   1403       s_arr[cnt] = i;
   1404       cnt++;
   1405     }
   1406   }
   1407 
   1408 #if (BTA_HL_DEBUG == TRUE)
   1409   APPL_TRACE_DEBUG("bta_hl_compact_mdl_cfg_time cnt=%d ", cnt);
   1410 #endif
   1411 
   1412   if (cnt) {
   1413     bta_hl_sort_cfg_time_idx(app_idx, s_arr, cnt);
   1414     time_min = BTA_HL_MIN_TIME;
   1415     for (i = 0; i < cnt; i++) {
   1416       p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, s_arr[i]);
   1417       p_mdl->time = time_min + i;
   1418       bta_hl_co_save_mdl(mdep_id, s_arr[i], p_mdl);
   1419     }
   1420   }
   1421 }
   1422 
   1423 /*******************************************************************************
   1424  *
   1425  * Function      bta_hl_is_mdl_exsit_in_mcl
   1426  *
   1427  * Description  This function checks whether the MDL ID
   1428  *              has already existed in teh MCL or not
   1429  *
   1430  * Returns      bool - true exist
   1431  *                        false does not exist
   1432  *
   1433  ******************************************************************************/
   1434 bool bta_hl_is_mdl_exsit_in_mcl(uint8_t app_idx, const RawAddress& bd_addr,
   1435                                 tBTA_HL_MDL_ID mdl_id) {
   1436   tBTA_HL_MDL_CFG* p_mdl;
   1437   bool found = false;
   1438   uint8_t i;
   1439 
   1440   for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
   1441     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
   1442     if (p_mdl->active && p_mdl->peer_bd_addr == bd_addr) {
   1443       if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) {
   1444         if (p_mdl->mdl_id == mdl_id) {
   1445           found = true;
   1446           break;
   1447         }
   1448       } else {
   1449         found = true;
   1450         break;
   1451       }
   1452     }
   1453   }
   1454 
   1455   return found;
   1456 }
   1457 
   1458 /*******************************************************************************
   1459  *
   1460  * Function      bta_hl_delete_mdl_cfg
   1461  *
   1462  * Description  This function delete the specified MDL ID
   1463  *
   1464  * Returns      bool - true Success
   1465  *                        false Failed
   1466  *
   1467  ******************************************************************************/
   1468 bool bta_hl_delete_mdl_cfg(uint8_t app_idx, const RawAddress& bd_addr,
   1469                            tBTA_HL_MDL_ID mdl_id) {
   1470   tBTA_HL_MDL_CFG* p_mdl;
   1471   bool success = false;
   1472   uint8_t i;
   1473 
   1474   for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
   1475     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
   1476     if (p_mdl->active && p_mdl->peer_bd_addr == bd_addr) {
   1477       if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) {
   1478         if (p_mdl->mdl_id == mdl_id) {
   1479           bta_hl_co_delete_mdl(p_mdl->local_mdep_id, i);
   1480           memset(p_mdl, 0, sizeof(tBTA_HL_MDL_CFG));
   1481           success = true;
   1482           break;
   1483         }
   1484       } else {
   1485         bta_hl_co_delete_mdl(p_mdl->local_mdep_id, i);
   1486         memset(p_mdl, 0, sizeof(tBTA_HL_MDL_CFG));
   1487         success = true;
   1488       }
   1489     }
   1490   }
   1491 
   1492   return success;
   1493 }
   1494 
   1495 /*******************************************************************************
   1496  *
   1497  * Function      bta_hl_is_mdl_value_valid
   1498  *
   1499  *
   1500  * Description  This function checks the specified MDL ID is in valid range.
   1501  *
   1502  * Returns      bool - true Success
   1503  *                        false Failed
   1504  *
   1505  * note:   mdl_id range   0x0000 reserved,
   1506  *                        0x0001-oxFEFF dynamic range,
   1507  *                        0xFF00-0xFFFE reserved,
   1508  *                        0xFFFF indicates all MDLs (for delete operation only)
   1509  *
   1510  ******************************************************************************/
   1511 bool bta_hl_is_mdl_value_valid(tBTA_HL_MDL_ID mdl_id) {
   1512   bool status = true;
   1513 
   1514   if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) {
   1515     if (mdl_id != 0) {
   1516       if (mdl_id > BTA_HL_MAX_MDL_VAL) {
   1517         status = false;
   1518       }
   1519     } else {
   1520       status = false;
   1521     }
   1522   }
   1523 
   1524   return status;
   1525 }
   1526 
   1527 /*******************************************************************************
   1528  *
   1529  * Function      bta_hl_find_mdep_cfg_idx
   1530  *
   1531  * Description  This function finds the MDEP configuration index based
   1532  *                on the local MDEP ID
   1533  *
   1534  * Returns      bool - true found
   1535  *                        false not found
   1536  *
   1537  ******************************************************************************/
   1538 bool bta_hl_find_mdep_cfg_idx(uint8_t app_idx, tBTA_HL_MDEP_ID local_mdep_id,
   1539                               uint8_t* p_mdep_cfg_idx) {
   1540   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   1541   tBTA_HL_SUP_FEATURE* p_sup_feature = &p_acb->sup_feature;
   1542   bool found = false;
   1543   uint8_t i;
   1544 
   1545   for (i = 0; i < p_sup_feature->num_of_mdeps; i++) {
   1546     if (p_sup_feature->mdep[i].mdep_id == local_mdep_id) {
   1547       found = true;
   1548       *p_mdep_cfg_idx = i;
   1549       break;
   1550     }
   1551   }
   1552 
   1553 #if (BTA_HL_DEBUG == TRUE)
   1554   if (!found) {
   1555     APPL_TRACE_DEBUG(
   1556         "bta_hl_find_mdep_cfg_idx found=%d mdep_idx=%d local_mdep_id=%d ",
   1557         found, i, local_mdep_id);
   1558   }
   1559 #endif
   1560   return found;
   1561 }
   1562 
   1563 /*******************************************************************************
   1564  *
   1565  * Function      bta_hl_find_rxtx_apdu_size
   1566  *
   1567  * Description  This function finds the maximum APDU rx and tx sizes based on
   1568  *              the MDEP configuration data
   1569  *
   1570  * Returns      void
   1571  *
   1572  ******************************************************************************/
   1573 void bta_hl_find_rxtx_apdu_size(uint8_t app_idx, uint8_t mdep_cfg_idx,
   1574                                 uint16_t* p_rx_apu_size,
   1575                                 uint16_t* p_tx_apu_size) {
   1576   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   1577   tBTA_HL_MDEP_CFG* p_mdep_cfg;
   1578   uint8_t i;
   1579   uint16_t max_rx_apdu_size = 0, max_tx_apdu_size = 0;
   1580 
   1581   p_mdep_cfg = &p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg;
   1582 
   1583   for (i = 0; i < p_mdep_cfg->num_of_mdep_data_types; i++) {
   1584     if (max_rx_apdu_size < p_mdep_cfg->data_cfg[i].max_rx_apdu_size) {
   1585       max_rx_apdu_size = p_mdep_cfg->data_cfg[i].max_rx_apdu_size;
   1586     }
   1587 
   1588     if (max_tx_apdu_size < p_mdep_cfg->data_cfg[i].max_tx_apdu_size) {
   1589       max_tx_apdu_size = p_mdep_cfg->data_cfg[i].max_tx_apdu_size;
   1590     }
   1591   }
   1592 
   1593   *p_rx_apu_size = max_rx_apdu_size;
   1594   *p_tx_apu_size = max_tx_apdu_size;
   1595 
   1596 #if (BTA_HL_DEBUG == TRUE)
   1597   APPL_TRACE_DEBUG(
   1598       "bta_hl_find_rxtx_apdu_size max_rx_apdu_size=%d max_tx_apdu_size=%d ",
   1599       max_rx_apdu_size, max_tx_apdu_size);
   1600 #endif
   1601 }
   1602 
   1603 /*******************************************************************************
   1604  *
   1605  * Function      bta_hl_validate_peer_cfg
   1606  *
   1607  * Description  This function validates the peer DCH configuration
   1608  *
   1609  * Returns      bool - true validation is successful
   1610  *                        false validation failed
   1611  *
   1612  ******************************************************************************/
   1613 bool bta_hl_validate_peer_cfg(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
   1614                               tBTA_HL_MDEP_ID peer_mdep_id,
   1615                               tBTA_HL_MDEP_ROLE peer_mdep_role,
   1616                               uint8_t sdp_idx) {
   1617   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
   1618   tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
   1619   tBTA_HL_SDP_REC* p_rec;
   1620   bool peer_found = false;
   1621   uint8_t i;
   1622 
   1623   APPL_TRACE_DEBUG("bta_hl_validate_peer_cfg sdp_idx=%d app_idx %d", sdp_idx,
   1624                    app_idx);
   1625 
   1626   if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) {
   1627     return true;
   1628   }
   1629 
   1630   p_rec = &p_mcb->sdp.sdp_rec[sdp_idx];
   1631   for (i = 0; i < p_rec->num_mdeps; i++) {
   1632     APPL_TRACE_DEBUG("mdep_id %d peer_mdep_id %d", p_rec->mdep_cfg[i].mdep_id,
   1633                      peer_mdep_id);
   1634     APPL_TRACE_DEBUG("mdep_role %d peer_mdep_role %d",
   1635                      p_rec->mdep_cfg[i].mdep_role, peer_mdep_role)
   1636     if ((p_rec->mdep_cfg[i].mdep_id == peer_mdep_id) &&
   1637         (p_rec->mdep_cfg[i].mdep_role == peer_mdep_role)) {
   1638       peer_found = true;
   1639 
   1640       break;
   1641     }
   1642   }
   1643 
   1644 #if (BTA_HL_DEBUG == TRUE)
   1645   if (!peer_found) {
   1646     APPL_TRACE_DEBUG("bta_hl_validate_peer_cfg failed num_mdeps=%d",
   1647                      p_rec->num_mdeps);
   1648   }
   1649 #endif
   1650   return peer_found;
   1651 }
   1652 
   1653 /*******************************************************************************
   1654  *
   1655  * Function      bta_hl_chk_local_cfg
   1656  *
   1657  * Description  This function check whether the local DCH configuration is OK.
   1658  *
   1659  * Returns      tBTA_HL_STATUS - OK - local DCH configuration is OK
   1660  *                               NO_FIRST_RELIABLE - the streaming DCH
   1661  *                                                   configuration is not OK and
   1662  *                                                   it needs to use reliable
   1663  *                                                   DCH configuration
   1664  *
   1665  ******************************************************************************/
   1666 tBTA_HL_STATUS bta_hl_chk_local_cfg(uint8_t app_idx, uint8_t mcl_idx,
   1667                                     uint8_t mdep_cfg_idx,
   1668                                     tBTA_HL_DCH_CFG local_cfg) {
   1669   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   1670   tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
   1671 
   1672   if (mdep_cfg_idx &&
   1673       (p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg.mdep_role ==
   1674        BTA_HL_MDEP_ROLE_SOURCE) &&
   1675       (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) &&
   1676       (local_cfg != BTA_HL_DCH_CFG_RELIABLE)) {
   1677     status = BTA_HL_STATUS_NO_FIRST_RELIABLE;
   1678     APPL_TRACE_ERROR("BTA_HL_STATUS_INVALID_DCH_CFG");
   1679   }
   1680 
   1681   return status;
   1682 }
   1683 
   1684 /*******************************************************************************
   1685  *
   1686  * Function      bta_hl_validate_reconnect_params
   1687  *
   1688  * Description  This function validates the reconnect parameters
   1689  *
   1690  * Returns      bool - true validation is successful
   1691  *                        false validation failed
   1692  ******************************************************************************/
   1693 bool bta_hl_validate_reconnect_params(uint8_t app_idx, uint8_t mcl_idx,
   1694                                       tBTA_HL_API_DCH_RECONNECT* p_reconnect,
   1695                                       uint8_t* p_mdep_cfg_idx,
   1696                                       uint8_t* p_mdl_cfg_idx) {
   1697   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   1698   tBTA_HL_SUP_FEATURE* p_sup_feature = &p_acb->sup_feature;
   1699   uint8_t num_mdeps;
   1700   uint8_t mdl_cfg_idx;
   1701   bool local_mdep_id_found = false;
   1702   bool mdl_cfg_found = false;
   1703   bool status = false;
   1704   uint8_t i, in_use_mdl_idx = 0;
   1705 
   1706 #if (BTA_HL_DEBUG == TRUE)
   1707   APPL_TRACE_DEBUG("bta_hl_validate_reconnect_params  mdl_id=%d app_idx=%d",
   1708                    p_reconnect->mdl_id, app_idx);
   1709 #endif
   1710   if (bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, p_reconnect->mdl_id,
   1711                               &mdl_cfg_idx)) {
   1712     mdl_cfg_found = true;
   1713   }
   1714 
   1715 #if (BTA_HL_DEBUG == TRUE)
   1716   if (!mdl_cfg_found) {
   1717     APPL_TRACE_DEBUG("mdl_cfg_found not found");
   1718   }
   1719 #endif
   1720 
   1721   if (mdl_cfg_found) {
   1722     num_mdeps = p_sup_feature->num_of_mdeps;
   1723     for (i = 0; i < num_mdeps; i++) {
   1724       if (p_sup_feature->mdep[i].mdep_id ==
   1725           p_acb->mdl_cfg[mdl_cfg_idx].local_mdep_id) {
   1726         local_mdep_id_found = true;
   1727         *p_mdep_cfg_idx = i;
   1728         *p_mdl_cfg_idx = mdl_cfg_idx;
   1729         break;
   1730       }
   1731     }
   1732   }
   1733 
   1734 #if (BTA_HL_DEBUG == TRUE)
   1735   if (!local_mdep_id_found) {
   1736     APPL_TRACE_DEBUG("local_mdep_id not found");
   1737   }
   1738 #endif
   1739 
   1740   if (local_mdep_id_found) {
   1741     if (!bta_hl_find_mdl_idx(app_idx, mcl_idx, p_reconnect->mdl_id,
   1742                              &in_use_mdl_idx)) {
   1743       status = true;
   1744     } else {
   1745       APPL_TRACE_ERROR("mdl_id=%d is curreltly in use", p_reconnect->mdl_id);
   1746     }
   1747   }
   1748 
   1749 #if (BTA_HL_DEBUG == TRUE)
   1750   if (!status) {
   1751     APPL_TRACE_DEBUG(
   1752         "Reconnect validation failed local_mdep_id found=%d mdl_cfg_idx "
   1753         "found=%d in_use_mdl_idx=%d ",
   1754         local_mdep_id_found, mdl_cfg_found, in_use_mdl_idx);
   1755   }
   1756 #endif
   1757   return status;
   1758 }
   1759 
   1760 /*******************************************************************************
   1761  *
   1762  * Function      bta_hl_find_avail_mcl_idx
   1763  *
   1764  * Returns      bool - true found
   1765  *                        false not found
   1766  *
   1767  ******************************************************************************/
   1768 bool bta_hl_find_avail_mcl_idx(uint8_t app_idx, uint8_t* p_mcl_idx) {
   1769   bool found = false;
   1770   uint8_t i;
   1771 
   1772   for (i = 0; i < BTA_HL_NUM_MCLS; i++) {
   1773     if (!bta_hl_cb.acb[app_idx].mcb[i].in_use) {
   1774       found = true;
   1775       *p_mcl_idx = i;
   1776       break;
   1777     }
   1778   }
   1779 
   1780 #if (BTA_HL_DEBUG == TRUE)
   1781   if (!found) {
   1782     APPL_TRACE_DEBUG("bta_hl_find_avail_mcl_idx found=%d idx=%d", found, i);
   1783   }
   1784 #endif
   1785   return found;
   1786 }
   1787 
   1788 /*******************************************************************************
   1789  *
   1790  * Function      bta_hl_find_avail_mdl_idx
   1791  *
   1792  * Description  This function finds an available MDL control block index
   1793  *
   1794  * Returns      bool - true found
   1795  *                        false not found
   1796  *
   1797  ******************************************************************************/
   1798 bool bta_hl_find_avail_mdl_idx(uint8_t app_idx, uint8_t mcl_idx,
   1799                                uint8_t* p_mdl_idx) {
   1800   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
   1801   bool found = false;
   1802   uint8_t i;
   1803 
   1804   for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
   1805     if (!p_mcb->mdl[i].in_use) {
   1806       memset((void*)&p_mcb->mdl[i], 0, sizeof(tBTA_HL_MDL_CB));
   1807       found = true;
   1808       *p_mdl_idx = i;
   1809       break;
   1810     }
   1811   }
   1812 
   1813 #if (BTA_HL_DEBUG == TRUE)
   1814   if (!found) {
   1815     APPL_TRACE_DEBUG("bta_hl_find_avail_mdl_idx found=%d idx=%d", found, i);
   1816   }
   1817 #endif
   1818   return found;
   1819 }
   1820 
   1821 /*******************************************************************************
   1822  *
   1823  * Function      bta_hl_is_a_duplicate_id
   1824  *
   1825  * Description  This function finds the application has been used or not
   1826  *
   1827  * Returns      bool - true the app_id is a duplicate ID
   1828  *                        false not a duplicate ID
   1829  ******************************************************************************/
   1830 bool bta_hl_is_a_duplicate_id(uint8_t app_id) {
   1831   bool is_duplicate = false;
   1832   uint8_t i;
   1833 
   1834   for (i = 0; i < BTA_HL_NUM_APPS; i++) {
   1835     if (bta_hl_cb.acb[i].in_use && (bta_hl_cb.acb[i].app_id == app_id)) {
   1836       is_duplicate = true;
   1837 
   1838       break;
   1839     }
   1840   }
   1841 
   1842 #if (BTA_HL_DEBUG == TRUE)
   1843   if (is_duplicate) {
   1844     APPL_TRACE_DEBUG("bta_hl_is_a_duplicate_id app_id=%d is_duplicate=%d",
   1845                      app_id, is_duplicate);
   1846   }
   1847 #endif
   1848 
   1849   return is_duplicate;
   1850 }
   1851 
   1852 /*******************************************************************************
   1853  *
   1854  * Function      bta_hl_find_avail_app_idx
   1855  *
   1856  * Description  This function finds an available application control block index
   1857  *
   1858  * Returns      bool - true found
   1859  *                        false not found
   1860  *
   1861  ******************************************************************************/
   1862 bool bta_hl_find_avail_app_idx(uint8_t* p_idx) {
   1863   bool found = false;
   1864   uint8_t i;
   1865 
   1866   for (i = 0; i < BTA_HL_NUM_APPS; i++) {
   1867     if (!bta_hl_cb.acb[i].in_use) {
   1868       found = true;
   1869       *p_idx = i;
   1870       break;
   1871     }
   1872   }
   1873 
   1874 #if (BTA_HL_DEBUG == TRUE)
   1875   if (!found) {
   1876     APPL_TRACE_DEBUG("bta_hl_find_avail_app_idx found=%d app_idx=%d", found, i);
   1877   }
   1878 #endif
   1879   return found;
   1880 }
   1881 
   1882 /*******************************************************************************
   1883  *
   1884  * Function      bta_hl_app_update
   1885  *
   1886  * Description  This function registers an HDP application MCAP and DP
   1887  *
   1888  * Returns      tBTA_HL_STATUS -registration status
   1889  *
   1890  ******************************************************************************/
   1891 tBTA_HL_STATUS bta_hl_app_update(uint8_t app_id, bool is_register) {
   1892   tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
   1893   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(0);
   1894   tMCA_CS mca_cs;
   1895   uint8_t i, mdep_idx, num_of_mdeps;
   1896   uint8_t mdep_counter = 0;
   1897 
   1898 #if (BTA_HL_DEBUG == TRUE)
   1899   APPL_TRACE_DEBUG("bta_hl_app_update app_id=%d", app_id);
   1900 #endif
   1901 
   1902   if (is_register) {
   1903     if ((status == BTA_HL_STATUS_OK) &&
   1904         bta_hl_co_get_num_of_mdep(app_id, &num_of_mdeps)) {
   1905       for (i = 0; i < num_of_mdeps; i++) {
   1906         mca_cs.type = MCA_TDEP_DATA;
   1907         mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP;
   1908         mca_cs.p_data_cback = bta_hl_mcap_data_cback;
   1909         /* Find the first available mdep index, and create a MDL Endpoint */
   1910         // make a function later if needed
   1911         for (mdep_idx = 1; mdep_idx < BTA_HL_NUM_MDEPS; mdep_idx++) {
   1912           if (p_acb->sup_feature.mdep[mdep_idx].mdep_id == 0) {
   1913             break; /* We found an available index */
   1914           } else {
   1915             mdep_counter++;
   1916           }
   1917         }
   1918         /* If no available MDEPs, return error */
   1919         if (mdep_idx == BTA_HL_NUM_MDEPS) {
   1920           APPL_TRACE_ERROR("bta_hl_app_update: Out of MDEP IDs");
   1921           status = BTA_HL_STATUS_MCAP_REG_FAIL;
   1922           break;
   1923         }
   1924         if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle,
   1925                           &(p_acb->sup_feature.mdep[mdep_idx].mdep_id),
   1926                           &mca_cs) == MCA_SUCCESS) {
   1927           if (bta_hl_co_get_mdep_config(
   1928                   app_id, mdep_idx, mdep_counter,
   1929                   p_acb->sup_feature.mdep[mdep_idx].mdep_id,
   1930                   &p_acb->sup_feature.mdep[mdep_idx].mdep_cfg)) {
   1931             p_acb->sup_feature.mdep[mdep_idx].ori_app_id = app_id;
   1932             APPL_TRACE_DEBUG("mdep idx %d id %d ori_app_id %d num data type %d",
   1933                              mdep_idx,
   1934                              p_acb->sup_feature.mdep[mdep_idx].mdep_id,
   1935                              p_acb->sup_feature.mdep[mdep_idx].ori_app_id,
   1936                              p_acb->sup_feature.mdep[mdep_idx]
   1937                                  .mdep_cfg.num_of_mdep_data_types);
   1938             if (p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role ==
   1939                 BTA_HL_MDEP_ROLE_SOURCE) {
   1940               p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SOURCE;
   1941             } else if (p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role ==
   1942                        BTA_HL_MDEP_ROLE_SINK) {
   1943               p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SINK;
   1944             } else {
   1945               APPL_TRACE_ERROR(
   1946                   "bta_hl_app_registration: Invalid Role %d",
   1947                   p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role);
   1948               status = BTA_HL_STATUS_MDEP_CO_FAIL;
   1949               break;
   1950             }
   1951           } else {
   1952             APPL_TRACE_ERROR("bta_hl_app_registration: Cfg callout failed");
   1953             status = BTA_HL_STATUS_MDEP_CO_FAIL;
   1954             break;
   1955           }
   1956         } else {
   1957           APPL_TRACE_ERROR("bta_hl_app_registration: MCA_CreateDep failed");
   1958           status = BTA_HL_STATUS_MCAP_REG_FAIL;
   1959           break;
   1960         }
   1961       }
   1962       p_acb->sup_feature.num_of_mdeps += num_of_mdeps;
   1963       APPL_TRACE_DEBUG("num_of_mdeps %d", p_acb->sup_feature.num_of_mdeps);
   1964 
   1965       if ((status == BTA_HL_STATUS_OK) &&
   1966           (p_acb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SOURCE)) {
   1967         p_acb->sup_feature.advertize_source_sdp =
   1968             bta_hl_co_advrtise_source_sdp(app_id);
   1969       }
   1970 
   1971       if ((status == BTA_HL_STATUS_OK) &&
   1972           (!bta_hl_co_get_echo_config(app_id, &p_acb->sup_feature.echo_cfg))) {
   1973         status = BTA_HL_STATUS_ECHO_CO_FAIL;
   1974       }
   1975 
   1976       if ((status == BTA_HL_STATUS_OK) &&
   1977           (!bta_hl_co_load_mdl_config(app_id, BTA_HL_NUM_MDL_CFGS,
   1978                                       &p_acb->mdl_cfg[0]))) {
   1979         status = BTA_HL_STATUS_MDL_CFG_CO_FAIL;
   1980       }
   1981     } else {
   1982       status = BTA_HL_STATUS_MDEP_CO_FAIL;
   1983     }
   1984   } else {
   1985     for (i = 1; i < BTA_HL_NUM_MDEPS; i++) {
   1986       if (p_acb->sup_feature.mdep[i].ori_app_id == app_id) {
   1987         APPL_TRACE_DEBUG("Found index %", i);
   1988 
   1989         if (MCA_DeleteDep((tMCA_HANDLE)p_acb->app_handle,
   1990                           (p_acb->sup_feature.mdep[i].mdep_id)) !=
   1991             MCA_SUCCESS) {
   1992           APPL_TRACE_ERROR("Error deregistering");
   1993           status = BTA_HL_STATUS_MCAP_REG_FAIL;
   1994           return status;
   1995         }
   1996         memset(&p_acb->sup_feature.mdep[i], 0, sizeof(tBTA_HL_MDEP));
   1997       }
   1998     }
   1999   }
   2000 
   2001   if (status == BTA_HL_STATUS_OK) {
   2002     /* Register/Update MDEP(s) in SDP Record */
   2003     status = bta_hl_sdp_update(app_id);
   2004   }
   2005   /* else do cleanup */
   2006 
   2007   return status;
   2008 }
   2009 
   2010 /*******************************************************************************
   2011  *
   2012  * Function      bta_hl_app_registration
   2013  *
   2014  * Description  This function registers an HDP application MCAP and DP
   2015  *
   2016  * Returns      tBTA_HL_STATUS -registration status
   2017  *
   2018  ******************************************************************************/
   2019 tBTA_HL_STATUS bta_hl_app_registration(uint8_t app_idx) {
   2020   tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
   2021   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   2022   tMCA_REG reg;
   2023   tMCA_CS mca_cs;
   2024   uint8_t i, num_of_mdeps;
   2025   uint8_t mdep_counter = 0;
   2026 
   2027 #if (BTA_HL_DEBUG == TRUE)
   2028   APPL_TRACE_DEBUG("bta_hl_app_registration app_idx=%d", app_idx);
   2029 #endif
   2030 
   2031   reg.ctrl_psm = p_acb->ctrl_psm;
   2032   reg.data_psm = p_acb->data_psm;
   2033   reg.sec_mask = p_acb->sec_mask;
   2034   reg.rsp_tout = BTA_HL_MCAP_RSP_TOUT;
   2035 
   2036   p_acb->app_handle =
   2037       (tBTA_HL_APP_HANDLE)MCA_Register(&reg, bta_hl_mcap_ctrl_cback);
   2038   if (p_acb->app_handle != 0) {
   2039     mca_cs.type = MCA_TDEP_ECHO;
   2040     mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP;
   2041     mca_cs.p_data_cback = bta_hl_mcap_data_cback;
   2042 
   2043     if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle,
   2044                       &(p_acb->sup_feature.mdep[0].mdep_id),
   2045                       &mca_cs) == MCA_SUCCESS) {
   2046       if (p_acb->sup_feature.mdep[0].mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) {
   2047         status = BTA_HL_STATUS_MCAP_REG_FAIL;
   2048         APPL_TRACE_ERROR("BAD MDEP ID for echo test mdep_id=%d",
   2049                          p_acb->sup_feature.mdep[0].mdep_id);
   2050       }
   2051     } else {
   2052       status = BTA_HL_STATUS_MCAP_REG_FAIL;
   2053       APPL_TRACE_ERROR("MCA_CreateDep for echo test(mdep_id=0) failed");
   2054     }
   2055 
   2056     if ((status == BTA_HL_STATUS_OK) &&
   2057         bta_hl_co_get_num_of_mdep(p_acb->app_id, &num_of_mdeps)) {
   2058       p_acb->sup_feature.num_of_mdeps = num_of_mdeps + 1;
   2059 
   2060       for (i = 1; i < p_acb->sup_feature.num_of_mdeps; i++) {
   2061         mca_cs.type = MCA_TDEP_DATA;
   2062         mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP;
   2063         mca_cs.p_data_cback = bta_hl_mcap_data_cback;
   2064 
   2065         if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle,
   2066                           &(p_acb->sup_feature.mdep[i].mdep_id),
   2067                           &mca_cs) == MCA_SUCCESS) {
   2068           if (bta_hl_co_get_mdep_config(p_acb->app_id, i, mdep_counter,
   2069                                         p_acb->sup_feature.mdep[i].mdep_id,
   2070                                         &p_acb->sup_feature.mdep[i].mdep_cfg)) {
   2071             if (p_acb->sup_feature.mdep[i].mdep_cfg.mdep_role ==
   2072                 BTA_HL_MDEP_ROLE_SOURCE) {
   2073               p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SOURCE;
   2074             } else if (p_acb->sup_feature.mdep[i].mdep_cfg.mdep_role ==
   2075                        BTA_HL_MDEP_ROLE_SINK) {
   2076               p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SINK;
   2077             } else {
   2078               status = BTA_HL_STATUS_MDEP_CO_FAIL;
   2079               break;
   2080             }
   2081             p_acb->sup_feature.mdep[i].ori_app_id = p_acb->app_id;
   2082             APPL_TRACE_DEBUG("index %d ori_app_id %d", i,
   2083                              p_acb->sup_feature.mdep[i].ori_app_id);
   2084           } else {
   2085             status = BTA_HL_STATUS_MDEP_CO_FAIL;
   2086             break;
   2087           }
   2088         } else {
   2089           status = BTA_HL_STATUS_MCAP_REG_FAIL;
   2090           break;
   2091         }
   2092       }
   2093 
   2094       if ((status == BTA_HL_STATUS_OK) &&
   2095           (p_acb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SOURCE)) {
   2096         /* this is a source only applciation */
   2097         p_acb->sup_feature.advertize_source_sdp =
   2098             bta_hl_co_advrtise_source_sdp(p_acb->app_id);
   2099       }
   2100 
   2101       if ((status == BTA_HL_STATUS_OK) &&
   2102           (!bta_hl_co_get_echo_config(p_acb->app_id,
   2103                                       &p_acb->sup_feature.echo_cfg))) {
   2104         status = BTA_HL_STATUS_ECHO_CO_FAIL;
   2105       }
   2106 
   2107       if ((status == BTA_HL_STATUS_OK) &&
   2108           (!bta_hl_co_load_mdl_config(p_acb->app_id, BTA_HL_NUM_MDL_CFGS,
   2109                                       &p_acb->mdl_cfg[0]))) {
   2110         status = BTA_HL_STATUS_MDL_CFG_CO_FAIL;
   2111       }
   2112     } else {
   2113       status = BTA_HL_STATUS_MDEP_CO_FAIL;
   2114     }
   2115   } else {
   2116     status = BTA_HL_STATUS_MCAP_REG_FAIL;
   2117   }
   2118 
   2119   if (status == BTA_HL_STATUS_OK) {
   2120     status = bta_hl_sdp_register(app_idx);
   2121   }
   2122 
   2123   return status;
   2124 }
   2125 
   2126 /*******************************************************************************
   2127  *
   2128  * Function         bta_hl_discard_data
   2129  *
   2130  * Description  This function discard an HDP event
   2131  *
   2132  * Returns     void
   2133  *
   2134  ******************************************************************************/
   2135 void bta_hl_discard_data(uint16_t event, tBTA_HL_DATA* p_data) {
   2136 #if (BTA_HL_DEBUG == TRUE)
   2137   APPL_TRACE_ERROR("BTA HL Discard event=%s", bta_hl_evt_code(event));
   2138 
   2139 #endif
   2140 
   2141   switch (event) {
   2142     case BTA_HL_API_SEND_DATA_EVT:
   2143       break;
   2144 
   2145     case BTA_HL_MCA_RCV_DATA_EVT:
   2146       osi_free_and_reset((void**)&p_data->mca_rcv_data_evt.p_pkt);
   2147       break;
   2148 
   2149     default:
   2150       /*Nothing to free*/
   2151       break;
   2152   }
   2153 }
   2154 
   2155 /*******************************************************************************
   2156  *
   2157  * Function         bta_hl_save_mdl_cfg
   2158  *
   2159  * Description    This function saves the MDL configuration
   2160  *
   2161  * Returns     void
   2162  *
   2163  ******************************************************************************/
   2164 void bta_hl_save_mdl_cfg(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx) {
   2165   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   2166   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
   2167   tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
   2168   uint8_t mdl_cfg_idx;
   2169   tBTA_HL_MDL_ID mdl_id;
   2170   bool found = true;
   2171   tBTA_HL_MDL_CFG mdl_cfg;
   2172   tBTA_HL_MDEP* p_mdep_cfg;
   2173   tBTA_HL_L2CAP_CFG_INFO l2cap_cfg;
   2174   uint8_t time_val = 0;
   2175   mdl_id = p_dcb->mdl_id;
   2176   if (!bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, mdl_id, &mdl_cfg_idx)) {
   2177     if (!bta_hl_find_avail_mdl_cfg_idx(app_idx, mcl_idx, &mdl_cfg_idx)) {
   2178       APPL_TRACE_ERROR("No space to save the MDL config");
   2179       found = false; /*no space available*/
   2180     }
   2181   }
   2182 
   2183   if (found) {
   2184     bta_hl_get_l2cap_cfg(p_dcb->mdl_handle, &l2cap_cfg);
   2185     if (!bta_hl_get_cur_time(app_idx, &time_val)) {
   2186       bta_hl_compact_mdl_cfg_time(app_idx, p_dcb->local_mdep_id);
   2187       bta_hl_get_cur_time(app_idx, &time_val);
   2188     }
   2189     mdl_cfg.active = true;
   2190     mdl_cfg.time = time_val;
   2191     mdl_cfg.mdl_id = p_dcb->mdl_id;
   2192     mdl_cfg.dch_mode = p_dcb->dch_mode;
   2193     mdl_cfg.mtu = l2cap_cfg.mtu;
   2194     mdl_cfg.fcs = l2cap_cfg.fcs;
   2195 
   2196     mdl_cfg.peer_bd_addr = p_mcb->bd_addr;
   2197     mdl_cfg.local_mdep_id = p_dcb->local_mdep_id;
   2198     p_mdep_cfg = &p_acb->sup_feature.mdep[p_dcb->local_mdep_cfg_idx];
   2199     mdl_cfg.local_mdep_role = p_mdep_cfg->mdep_cfg.mdep_role;
   2200     memcpy(&p_acb->mdl_cfg[mdl_cfg_idx], &mdl_cfg, sizeof(tBTA_HL_MDL_CFG));
   2201     bta_hl_co_save_mdl(mdl_cfg.local_mdep_id, mdl_cfg_idx, &mdl_cfg);
   2202   }
   2203 
   2204 #if (BTA_HL_DEBUG == TRUE)
   2205   if (found) {
   2206     if (p_dcb->mtu != l2cap_cfg.mtu) {
   2207       APPL_TRACE_WARNING(
   2208           "MCAP and L2CAP peer mtu size out of sync from MCAP mtu=%d from "
   2209           "l2cap mtu=%d",
   2210           p_dcb->mtu, l2cap_cfg.mtu);
   2211     }
   2212     APPL_TRACE_DEBUG("bta_hl_save_mdl_cfg saved=%d", found);
   2213     APPL_TRACE_DEBUG("Saved. L2cap cfg mdl_id=%d mtu=%d fcs=%d dch_mode=%d",
   2214                      mdl_cfg.mdl_id, mdl_cfg.mtu, mdl_cfg.fcs,
   2215                      mdl_cfg.dch_mode);
   2216   }
   2217 #endif
   2218 }
   2219 
   2220 /*******************************************************************************
   2221  *
   2222  * Function      bta_hl_set_dch_chan_cfg
   2223  *
   2224  * Description    This function setups the L2CAP DCH channel configuration
   2225  *
   2226  * Returns     void
   2227  ******************************************************************************/
   2228 void bta_hl_set_dch_chan_cfg(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
   2229                              tBTA_HL_DATA* p_data) {
   2230   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   2231   tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
   2232   uint8_t l2cap_mode = L2CAP_FCR_ERTM_MODE;
   2233   tBTA_HL_SUP_FEATURE* p_sup_feature = &p_acb->sup_feature;
   2234   uint8_t local_mdep_cfg_idx = p_dcb->local_mdep_cfg_idx;
   2235 
   2236   switch (p_dcb->dch_oper) {
   2237     case BTA_HL_DCH_OP_LOCAL_RECONNECT:
   2238     case BTA_HL_DCH_OP_REMOTE_RECONNECT:
   2239       if (p_dcb->dch_mode == BTA_HL_DCH_MODE_STREAMING)
   2240         l2cap_mode = L2CAP_FCR_STREAM_MODE;
   2241       break;
   2242     case BTA_HL_DCH_OP_LOCAL_OPEN:
   2243       if (p_data->mca_evt.mca_data.create_cfm.cfg == BTA_HL_DCH_CFG_STREAMING)
   2244         l2cap_mode = L2CAP_FCR_STREAM_MODE;
   2245       break;
   2246     case BTA_HL_DCH_OP_REMOTE_OPEN:
   2247       if (p_dcb->local_cfg == BTA_HL_DCH_CFG_STREAMING)
   2248         l2cap_mode = L2CAP_FCR_STREAM_MODE;
   2249       break;
   2250     default:
   2251       APPL_TRACE_ERROR("Invalid dch oper=%d for set dch chan cfg",
   2252                        p_dcb->dch_oper);
   2253       break;
   2254   }
   2255   p_dcb->chnl_cfg.fcr_opt.mode = l2cap_mode;
   2256   p_dcb->chnl_cfg.fcr_opt.mps = bta_hl_set_mps(p_dcb->max_rx_apdu_size);
   2257   p_dcb->chnl_cfg.fcr_opt.tx_win_sz = bta_hl_set_tx_win_size(
   2258       p_dcb->max_rx_apdu_size, p_dcb->chnl_cfg.fcr_opt.mps);
   2259   p_dcb->chnl_cfg.fcr_opt.max_transmit = BTA_HL_L2C_MAX_TRANSMIT;
   2260   p_dcb->chnl_cfg.fcr_opt.rtrans_tout = BTA_HL_L2C_RTRANS_TOUT;
   2261   p_dcb->chnl_cfg.fcr_opt.mon_tout = BTA_HL_L2C_MON_TOUT;
   2262 
   2263   p_dcb->chnl_cfg.user_rx_buf_size =
   2264       bta_hl_set_user_rx_buf_size(p_dcb->max_rx_apdu_size);
   2265   p_dcb->chnl_cfg.user_tx_buf_size =
   2266       bta_hl_set_user_tx_buf_size(p_dcb->max_tx_apdu_size);
   2267   p_dcb->chnl_cfg.fcr_rx_buf_size = L2CAP_INVALID_ERM_BUF_SIZE;
   2268   p_dcb->chnl_cfg.fcr_tx_buf_size = L2CAP_INVALID_ERM_BUF_SIZE;
   2269   p_dcb->chnl_cfg.data_mtu = p_dcb->max_rx_apdu_size;
   2270 
   2271   p_dcb->chnl_cfg.fcs = BTA_HL_MCA_NO_FCS;
   2272   if (local_mdep_cfg_idx != BTA_HL_ECHO_TEST_MDEP_CFG_IDX) {
   2273     if (p_sup_feature->mdep[local_mdep_cfg_idx].mdep_cfg.mdep_role ==
   2274         BTA_HL_MDEP_ROLE_SOURCE) {
   2275       p_dcb->chnl_cfg.fcs = BTA_HL_DEFAULT_SOURCE_FCS;
   2276     }
   2277   } else {
   2278     p_dcb->chnl_cfg.fcs = BTA_HL_MCA_USE_FCS;
   2279   }
   2280 
   2281 #if (BTA_HL_DEBUG == TRUE)
   2282   APPL_TRACE_DEBUG("L2CAP Params l2cap_mode[3-ERTM 4-STREAM]=%d", l2cap_mode);
   2283   APPL_TRACE_DEBUG("Use FCS =%s mtu=%d",
   2284                    ((p_dcb->chnl_cfg.fcs & 1) ? "YES" : "NO"),
   2285                    p_dcb->chnl_cfg.data_mtu);
   2286   APPL_TRACE_DEBUG(
   2287       "tx_win_sz=%d, max_transmit=%d, rtrans_tout=%d, mon_tout=%d, mps=%d",
   2288       p_dcb->chnl_cfg.fcr_opt.tx_win_sz, p_dcb->chnl_cfg.fcr_opt.max_transmit,
   2289       p_dcb->chnl_cfg.fcr_opt.rtrans_tout, p_dcb->chnl_cfg.fcr_opt.mon_tout,
   2290       p_dcb->chnl_cfg.fcr_opt.mps);
   2291 
   2292   APPL_TRACE_DEBUG(
   2293       "USER rx_buf_size=%d, tx_buf_size=%d, FCR rx_buf_size=%d, tx_buf_size=%d",
   2294       p_dcb->chnl_cfg.user_rx_buf_size, p_dcb->chnl_cfg.user_tx_buf_size,
   2295       p_dcb->chnl_cfg.fcr_rx_buf_size, p_dcb->chnl_cfg.fcr_tx_buf_size);
   2296 
   2297 #endif
   2298 }
   2299 
   2300 /*******************************************************************************
   2301  *
   2302  * Function      bta_hl_get_l2cap_cfg
   2303  *
   2304  * Description    This function get the current L2CAP channel configuration
   2305  *
   2306  * Returns     bool - true - operation is successful
   2307  ******************************************************************************/
   2308 bool bta_hl_get_l2cap_cfg(tBTA_HL_MDL_HANDLE mdl_hnd,
   2309                           tBTA_HL_L2CAP_CFG_INFO* p_cfg) {
   2310   bool success = false;
   2311   uint16_t lcid;
   2312   tL2CAP_CFG_INFO* p_our_cfg;
   2313   tL2CAP_CH_CFG_BITS our_cfg_bits;
   2314   tL2CAP_CFG_INFO* p_peer_cfg;
   2315   tL2CAP_CH_CFG_BITS peer_cfg_bits;
   2316 
   2317   lcid = MCA_GetL2CapChannel((tMCA_DL)mdl_hnd);
   2318   if (lcid && L2CA_GetCurrentConfig(lcid, &p_our_cfg, &our_cfg_bits,
   2319                                     &p_peer_cfg, &peer_cfg_bits)) {
   2320     p_cfg->fcs = BTA_HL_MCA_NO_FCS;
   2321     if (our_cfg_bits & L2CAP_CH_CFG_MASK_FCS) {
   2322       p_cfg->fcs |= p_our_cfg->fcs;
   2323     } else {
   2324       p_cfg->fcs = BTA_HL_MCA_USE_FCS;
   2325     }
   2326 
   2327     if (p_cfg->fcs != BTA_HL_MCA_USE_FCS) {
   2328       if (peer_cfg_bits & L2CAP_CH_CFG_MASK_FCS) {
   2329         p_cfg->fcs |= p_peer_cfg->fcs;
   2330       } else {
   2331         p_cfg->fcs = BTA_HL_MCA_USE_FCS;
   2332       }
   2333     }
   2334 
   2335     p_cfg->mtu = 0;
   2336     if (peer_cfg_bits & L2CAP_CH_CFG_MASK_MTU) {
   2337       p_cfg->mtu = p_peer_cfg->mtu;
   2338     } else {
   2339       p_cfg->mtu = L2CAP_DEFAULT_MTU;
   2340     }
   2341     success = true;
   2342   } else {
   2343     p_cfg->mtu = L2CAP_DEFAULT_MTU;
   2344     p_cfg->fcs = BTA_HL_L2C_NO_FCS;
   2345   }
   2346 
   2347 #if (BTA_HL_DEBUG == TRUE)
   2348   if (!success) {
   2349     APPL_TRACE_DEBUG("bta_hl_get_l2cap_cfg success=%d mdl=%d lcid=%d", success,
   2350                      mdl_hnd, lcid);
   2351     APPL_TRACE_DEBUG("l2cap mtu=%d fcs=%d", p_cfg->mtu, p_cfg->fcs);
   2352   }
   2353 #endif
   2354 
   2355   return success;
   2356 }
   2357 
   2358 /*******************************************************************************
   2359  *
   2360  * Function      bta_hl_validate_chan_cfg
   2361  *
   2362  * Description    This function validates the L2CAP channel configuration
   2363  *
   2364  * Returns     bool - true - validation is successful
   2365  ******************************************************************************/
   2366 bool bta_hl_validate_chan_cfg(uint8_t app_idx, uint8_t mcl_idx,
   2367                               uint8_t mdl_idx) {
   2368   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   2369   tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
   2370   bool success = false;
   2371   uint8_t mdl_cfg_idx = 0;
   2372   tBTA_HL_L2CAP_CFG_INFO l2cap_cfg;
   2373   bool get_l2cap_result, get_mdl_result;
   2374 
   2375   get_l2cap_result = bta_hl_get_l2cap_cfg(p_dcb->mdl_handle, &l2cap_cfg);
   2376   get_mdl_result =
   2377       bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, p_dcb->mdl_id, &mdl_cfg_idx);
   2378 
   2379   if (get_l2cap_result && get_mdl_result) {
   2380     if ((p_acb->mdl_cfg[mdl_cfg_idx].mtu <= l2cap_cfg.mtu) &&
   2381         (p_acb->mdl_cfg[mdl_cfg_idx].fcs == l2cap_cfg.fcs) &&
   2382         (p_acb->mdl_cfg[mdl_cfg_idx].dch_mode == p_dcb->dch_mode)) {
   2383       success = true;
   2384     }
   2385   }
   2386 
   2387 #if (BTA_HL_DEBUG == TRUE)
   2388 
   2389   if (p_dcb->mtu != l2cap_cfg.mtu) {
   2390     APPL_TRACE_WARNING(
   2391         "MCAP and L2CAP peer mtu size out of sync from MCAP mtu=%d from l2cap "
   2392         "mtu=%d",
   2393         p_dcb->mtu, l2cap_cfg.mtu);
   2394   }
   2395 
   2396   if (!success) {
   2397     APPL_TRACE_DEBUG(
   2398         "bta_hl_validate_chan_cfg success=%d app_idx=%d mcl_idx=%d mdl_idx=%d",
   2399         success, app_idx, mcl_idx, mdl_idx);
   2400     APPL_TRACE_DEBUG("Cur. L2cap cfg mtu=%d fcs=%d dch_mode=%d", l2cap_cfg.mtu,
   2401                      l2cap_cfg.fcs, p_dcb->dch_mode);
   2402     APPL_TRACE_DEBUG("From saved: L2cap cfg mtu=%d fcs=%d dch_mode=%d",
   2403                      p_acb->mdl_cfg[mdl_cfg_idx].mtu,
   2404                      p_acb->mdl_cfg[mdl_cfg_idx].fcs,
   2405                      p_acb->mdl_cfg[mdl_cfg_idx].dch_mode);
   2406   }
   2407 #endif
   2408 
   2409   return success;
   2410 }
   2411 
   2412 /*******************************************************************************
   2413  *
   2414  * Function      bta_hl_is_cong_on
   2415  *
   2416  * Description    This function checks whether the congestion condition is on.
   2417  *
   2418  * Returns      bool - true DCH is congested
   2419  *                        false not congested
   2420  *
   2421  ******************************************************************************/
   2422 bool bta_hl_is_cong_on(uint8_t app_id, const RawAddress& bd_addr,
   2423                        tBTA_HL_MDL_ID mdl_id)
   2424 
   2425 {
   2426   tBTA_HL_MDL_CB* p_dcb;
   2427   uint8_t app_idx = 0, mcl_idx, mdl_idx;
   2428   bool cong_status = true;
   2429 
   2430   if (bta_hl_find_app_idx(app_id, &app_idx)) {
   2431     if (bta_hl_find_mcl_idx(app_idx, bd_addr, &mcl_idx)) {
   2432       if (bta_hl_find_mdl_idx(app_idx, mcl_idx, mdl_id, &mdl_idx)) {
   2433         p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
   2434         cong_status = p_dcb->cong;
   2435       }
   2436     }
   2437   }
   2438 
   2439   return cong_status;
   2440 }
   2441 
   2442 /*******************************************************************************
   2443  *
   2444  * Function      bta_hl_check_cch_close
   2445  *
   2446  * Description   This function checks whether there is a pending CCH close
   2447  *               request or not
   2448  *
   2449  * Returns      void
   2450  ******************************************************************************/
   2451 void bta_hl_check_cch_close(uint8_t app_idx, uint8_t mcl_idx,
   2452                             tBTA_HL_DATA* p_data, bool check_dch_setup) {
   2453   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
   2454   tBTA_HL_MDL_CB* p_dcb;
   2455   uint8_t mdl_idx;
   2456 
   2457 #if (BTA_HL_DEBUG == TRUE)
   2458   APPL_TRACE_DEBUG("bta_hl_check_cch_close cch_close_dch_oper=%d",
   2459                    p_mcb->cch_close_dch_oper);
   2460 #endif
   2461 
   2462   if (p_mcb->cch_oper == BTA_HL_CCH_OP_LOCAL_CLOSE) {
   2463     if (check_dch_setup &&
   2464         bta_hl_find_dch_setup_mdl_idx(app_idx, mcl_idx, &mdl_idx)) {
   2465       p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
   2466       if (!p_mcb->rsp_tout) {
   2467         p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_ABORT;
   2468 
   2469         if (!p_dcb->abort_oper) {
   2470           p_dcb->abort_oper |= BTA_HL_ABORT_CCH_CLOSE_MASK;
   2471           bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_ABORT_EVT,
   2472                                 p_data);
   2473         }
   2474       } else {
   2475         p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_CLOSE;
   2476         bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
   2477                               BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
   2478       }
   2479     } else if (bta_hl_find_an_active_mdl_idx(app_idx, mcl_idx, &mdl_idx)) {
   2480       p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_CLOSE;
   2481       bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_EVT,
   2482                             p_data);
   2483     } else {
   2484       p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_NONE;
   2485       bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_EVT, p_data);
   2486     }
   2487   }
   2488 }
   2489 
   2490 /*******************************************************************************
   2491  *
   2492  * Function         bta_hl_clean_app
   2493  *
   2494  * Description      Cleans up the HDP application resources and control block
   2495  *
   2496  * Returns          void
   2497  *
   2498  ******************************************************************************/
   2499 void bta_hl_clean_app(uint8_t app_idx) {
   2500   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   2501   int i, num_act_apps = 0;
   2502 
   2503 #if (BTA_HL_DEBUG == TRUE)
   2504   APPL_TRACE_DEBUG("bta_hl_clean_app");
   2505 #endif
   2506   MCA_Deregister((tMCA_HANDLE)p_acb->app_handle);
   2507 
   2508   if (p_acb->sdp_handle) SDP_DeleteRecord(p_acb->sdp_handle);
   2509 
   2510   memset((void*)p_acb, 0, sizeof(tBTA_HL_APP_CB));
   2511 
   2512   /* check any application is still active */
   2513   for (i = 0; i < BTA_HL_NUM_APPS; i++) {
   2514     p_acb = BTA_HL_GET_APP_CB_PTR(i);
   2515     if (p_acb->in_use) num_act_apps++;
   2516   }
   2517 
   2518   if (!num_act_apps) {
   2519     bta_sys_remove_uuid(UUID_SERVCLASS_HDP_PROFILE);
   2520   }
   2521 }
   2522 
   2523 /*******************************************************************************
   2524  *
   2525  * Function      bta_hl_check_deregistration
   2526  *
   2527  * Description   This function checks whether there is a pending deregistration
   2528  *               request or not
   2529  *
   2530  * Returns      void
   2531  ******************************************************************************/
   2532 void bta_hl_check_deregistration(uint8_t app_idx, tBTA_HL_DATA* p_data) {
   2533   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   2534   tBTA_HL_MCL_CB* p_mcb;
   2535   uint8_t mcl_idx;
   2536   tBTA_HL evt_data;
   2537 
   2538 #if (BTA_HL_DEBUG == TRUE)
   2539   APPL_TRACE_DEBUG("bta_hl_check_deregistration");
   2540 #endif
   2541 
   2542   if (p_acb->deregistering) {
   2543     if (bta_hl_find_an_in_use_mcl_idx(app_idx, &mcl_idx)) {
   2544       p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
   2545       if (p_mcb->cch_oper != BTA_HL_CCH_OP_LOCAL_CLOSE) {
   2546         if (p_mcb->cch_state == BTA_HL_CCH_OPENING_ST)
   2547           p_mcb->force_close_local_cch_opening = true;
   2548         p_mcb->cch_oper = BTA_HL_CCH_OP_LOCAL_CLOSE;
   2549         APPL_TRACE_DEBUG("p_mcb->force_close_local_cch_opening=%d",
   2550                          p_mcb->force_close_local_cch_opening);
   2551         bta_hl_check_cch_close(app_idx, mcl_idx, p_data, true);
   2552       }
   2553     } else {
   2554       /* all cchs are closed */
   2555       evt_data.dereg_cfm.app_handle = p_acb->app_handle;
   2556       evt_data.dereg_cfm.app_id = p_data->api_dereg.app_id;
   2557       evt_data.dereg_cfm.status = BTA_HL_STATUS_OK;
   2558       p_acb->p_cback(BTA_HL_DEREGISTER_CFM_EVT, (tBTA_HL*)&evt_data);
   2559       bta_hl_clean_app(app_idx);
   2560       bta_hl_check_disable(p_data);
   2561     }
   2562   }
   2563 }
   2564 
   2565 /*******************************************************************************
   2566  *
   2567  * Function      bta_hl_check_disable
   2568  *
   2569  * Description   This function checks whether there is a pending disable
   2570  *               request or not
   2571  *
   2572  * Returns      void
   2573  *
   2574  ******************************************************************************/
   2575 void bta_hl_check_disable(tBTA_HL_DATA* p_data) {
   2576   tBTA_HL_CB* p_cb = &bta_hl_cb;
   2577   tBTA_HL_APP_CB* p_acb;
   2578   uint8_t app_idx;
   2579   tBTA_HL_CTRL evt_data;
   2580 
   2581 #if (BTA_HL_DEBUG == TRUE)
   2582   APPL_TRACE_DEBUG("bta_hl_check_disable");
   2583 #endif
   2584 
   2585   if (bta_hl_cb.disabling) {
   2586     if (bta_hl_find_an_in_use_app_idx(&app_idx)) {
   2587       p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   2588       if (!p_acb->deregistering) {
   2589         p_acb->deregistering = true;
   2590         bta_hl_check_deregistration(app_idx, p_data);
   2591       }
   2592     } else {
   2593       /* all apps are deregistered */
   2594       bta_sys_deregister(BTA_ID_HL);
   2595       evt_data.disable_cfm.status = BTA_HL_STATUS_OK;
   2596       if (p_cb->p_ctrl_cback)
   2597         p_cb->p_ctrl_cback(BTA_HL_CTRL_DISABLE_CFM_EVT,
   2598                            (tBTA_HL_CTRL*)&evt_data);
   2599       memset((void*)p_cb, 0, sizeof(tBTA_HL_CB));
   2600     }
   2601   }
   2602 }
   2603 
   2604 /*******************************************************************************
   2605  *
   2606  * Function      bta_hl_build_abort_cfm
   2607  *
   2608  * Description   This function builds the abort confirmation event data
   2609  *
   2610  * Returns      None
   2611  *
   2612  ******************************************************************************/
   2613 void bta_hl_build_abort_cfm(tBTA_HL* p_evt_data, tBTA_HL_APP_HANDLE app_handle,
   2614                             tBTA_HL_MCL_HANDLE mcl_handle,
   2615                             tBTA_HL_STATUS status) {
   2616   p_evt_data->dch_abort_cfm.status = status;
   2617   p_evt_data->dch_abort_cfm.mcl_handle = mcl_handle;
   2618   p_evt_data->dch_abort_cfm.app_handle = app_handle;
   2619 }
   2620 
   2621 /*******************************************************************************
   2622  *
   2623  * Function      bta_hl_build_abort_ind
   2624  *
   2625  * Description   This function builds the abort indication event data
   2626  *
   2627  * Returns      None
   2628  *
   2629  ******************************************************************************/
   2630 void bta_hl_build_abort_ind(tBTA_HL* p_evt_data, tBTA_HL_APP_HANDLE app_handle,
   2631                             tBTA_HL_MCL_HANDLE mcl_handle) {
   2632   p_evt_data->dch_abort_ind.mcl_handle = mcl_handle;
   2633   p_evt_data->dch_abort_ind.app_handle = app_handle;
   2634 }
   2635 /*******************************************************************************
   2636  *
   2637  * Function      bta_hl_build_close_cfm
   2638  *
   2639  * Description   This function builds the close confirmation event data
   2640  *
   2641  * Returns      None
   2642  *
   2643  ******************************************************************************/
   2644 void bta_hl_build_dch_close_cfm(tBTA_HL* p_evt_data,
   2645                                 tBTA_HL_APP_HANDLE app_handle,
   2646                                 tBTA_HL_MCL_HANDLE mcl_handle,
   2647                                 tBTA_HL_MDL_HANDLE mdl_handle,
   2648                                 tBTA_HL_STATUS status) {
   2649   p_evt_data->dch_close_cfm.status = status;
   2650   p_evt_data->dch_close_cfm.mdl_handle = mdl_handle;
   2651   p_evt_data->dch_close_cfm.mcl_handle = mcl_handle;
   2652   p_evt_data->dch_close_cfm.app_handle = app_handle;
   2653 }
   2654 
   2655 /*******************************************************************************
   2656  *
   2657  * Function      bta_hl_build_dch_close_ind
   2658  *
   2659  * Description   This function builds the close indication event data
   2660  *
   2661  * Returns      None
   2662  *
   2663  ******************************************************************************/
   2664 void bta_hl_build_dch_close_ind(tBTA_HL* p_evt_data,
   2665                                 tBTA_HL_APP_HANDLE app_handle,
   2666                                 tBTA_HL_MCL_HANDLE mcl_handle,
   2667                                 tBTA_HL_MDL_HANDLE mdl_handle,
   2668                                 bool intentional) {
   2669   p_evt_data->dch_close_ind.mdl_handle = mdl_handle;
   2670   p_evt_data->dch_close_ind.mcl_handle = mcl_handle;
   2671   p_evt_data->dch_close_ind.app_handle = app_handle;
   2672   p_evt_data->dch_close_ind.intentional = intentional;
   2673 }
   2674 
   2675 /*******************************************************************************
   2676  *
   2677  * Function      bta_hl_build_send_data_cfm
   2678  *
   2679  * Description   This function builds the send data confirmation event data
   2680  *
   2681  * Returns      None
   2682  *
   2683  ******************************************************************************/
   2684 void bta_hl_build_send_data_cfm(tBTA_HL* p_evt_data,
   2685                                 tBTA_HL_APP_HANDLE app_handle,
   2686                                 tBTA_HL_MCL_HANDLE mcl_handle,
   2687                                 tBTA_HL_MDL_HANDLE mdl_handle,
   2688                                 tBTA_HL_STATUS status) {
   2689   p_evt_data->dch_send_data_cfm.mdl_handle = mdl_handle;
   2690   p_evt_data->dch_send_data_cfm.mcl_handle = mcl_handle;
   2691   p_evt_data->dch_send_data_cfm.app_handle = app_handle;
   2692   p_evt_data->dch_send_data_cfm.status = status;
   2693 }
   2694 
   2695 /*******************************************************************************
   2696  *
   2697  * Function      bta_hl_build_rcv_data_ind
   2698  *
   2699  * Description   This function builds the received data indication event data
   2700  *
   2701  * Returns      None
   2702  *
   2703  ******************************************************************************/
   2704 void bta_hl_build_rcv_data_ind(tBTA_HL* p_evt_data,
   2705                                tBTA_HL_APP_HANDLE app_handle,
   2706                                tBTA_HL_MCL_HANDLE mcl_handle,
   2707                                tBTA_HL_MDL_HANDLE mdl_handle) {
   2708   p_evt_data->dch_rcv_data_ind.mdl_handle = mdl_handle;
   2709   p_evt_data->dch_rcv_data_ind.mcl_handle = mcl_handle;
   2710   p_evt_data->dch_rcv_data_ind.app_handle = app_handle;
   2711 }
   2712 
   2713 /*******************************************************************************
   2714  *
   2715  * Function      bta_hl_build_cch_open_cfm
   2716  *
   2717  * Description   This function builds the CCH open confirmation event data
   2718  *
   2719  * Returns      None
   2720  *
   2721  ******************************************************************************/
   2722 void bta_hl_build_cch_open_cfm(tBTA_HL* p_evt_data, uint8_t app_id,
   2723                                tBTA_HL_APP_HANDLE app_handle,
   2724                                tBTA_HL_MCL_HANDLE mcl_handle,
   2725                                const RawAddress& bd_addr,
   2726                                tBTA_HL_STATUS status) {
   2727   p_evt_data->cch_open_cfm.app_id = app_id;
   2728   p_evt_data->cch_open_cfm.app_handle = app_handle;
   2729   p_evt_data->cch_open_cfm.mcl_handle = mcl_handle;
   2730   p_evt_data->cch_open_cfm.bd_addr = bd_addr;
   2731   p_evt_data->cch_open_cfm.status = status;
   2732   APPL_TRACE_DEBUG("bta_hl_build_cch_open_cfm: status=%d", status);
   2733 }
   2734 
   2735 /*******************************************************************************
   2736  *
   2737  * Function      bta_hl_build_cch_open_ind
   2738  *
   2739  * Description   This function builds the CCH open indication event data
   2740  *
   2741  * Returns      None
   2742  *
   2743  ******************************************************************************/
   2744 void bta_hl_build_cch_open_ind(tBTA_HL* p_evt_data,
   2745                                tBTA_HL_APP_HANDLE app_handle,
   2746                                tBTA_HL_MCL_HANDLE mcl_handle,
   2747                                const RawAddress& bd_addr) {
   2748   p_evt_data->cch_open_ind.app_handle = app_handle;
   2749   p_evt_data->cch_open_ind.mcl_handle = mcl_handle;
   2750   p_evt_data->cch_open_ind.bd_addr = bd_addr;
   2751 }
   2752 
   2753 /*******************************************************************************
   2754  *
   2755  * Function      bta_hl_build_cch_close_cfm
   2756  *
   2757  * Description   This function builds the CCH close confirmation event data
   2758  *
   2759  * Returns      None
   2760  *
   2761  ******************************************************************************/
   2762 void bta_hl_build_cch_close_cfm(tBTA_HL* p_evt_data,
   2763                                 tBTA_HL_APP_HANDLE app_handle,
   2764                                 tBTA_HL_MCL_HANDLE mcl_handle,
   2765                                 tBTA_HL_STATUS status) {
   2766   p_evt_data->cch_close_cfm.mcl_handle = mcl_handle;
   2767   p_evt_data->cch_close_cfm.app_handle = app_handle;
   2768   p_evt_data->cch_close_cfm.status = status;
   2769 }
   2770 
   2771 /*******************************************************************************
   2772  *
   2773  * Function      bta_hl_build_cch_close_ind
   2774  *
   2775  * Description   This function builds the CCH colse indication event data
   2776  *
   2777  * Returns      None
   2778  *
   2779  ******************************************************************************/
   2780 void bta_hl_build_cch_close_ind(tBTA_HL* p_evt_data,
   2781                                 tBTA_HL_APP_HANDLE app_handle,
   2782                                 tBTA_HL_MCL_HANDLE mcl_handle,
   2783                                 bool intentional) {
   2784   p_evt_data->cch_close_ind.mcl_handle = mcl_handle;
   2785   p_evt_data->cch_close_ind.app_handle = app_handle;
   2786   p_evt_data->cch_close_ind.intentional = intentional;
   2787 }
   2788 
   2789 /*******************************************************************************
   2790  *
   2791  * Function      bta_hl_build_dch_open_cfm
   2792  *
   2793  * Description   This function builds the DCH open confirmation event data
   2794  *
   2795  * Returns      None
   2796  *
   2797  ******************************************************************************/
   2798 void bta_hl_build_dch_open_cfm(tBTA_HL* p_evt_data,
   2799                                tBTA_HL_APP_HANDLE app_handle,
   2800                                tBTA_HL_MCL_HANDLE mcl_handle,
   2801                                tBTA_HL_MDL_HANDLE mdl_handle,
   2802                                tBTA_HL_MDEP_ID local_mdep_id,
   2803                                tBTA_HL_MDL_ID mdl_id, tBTA_HL_DCH_MODE dch_mode,
   2804                                bool first_reliable, uint16_t mtu,
   2805                                tBTA_HL_STATUS status)
   2806 
   2807 {
   2808   p_evt_data->dch_open_cfm.mdl_handle = mdl_handle;
   2809   p_evt_data->dch_open_cfm.mcl_handle = mcl_handle;
   2810   p_evt_data->dch_open_cfm.app_handle = app_handle;
   2811   p_evt_data->dch_open_cfm.local_mdep_id = local_mdep_id;
   2812   p_evt_data->dch_open_cfm.mdl_id = mdl_id;
   2813   p_evt_data->dch_open_cfm.dch_mode = dch_mode;
   2814   p_evt_data->dch_open_cfm.first_reliable = first_reliable;
   2815   p_evt_data->dch_open_cfm.mtu = mtu;
   2816   p_evt_data->dch_open_cfm.status = status;
   2817 }
   2818 
   2819 /*******************************************************************************
   2820  *
   2821  * Function      bta_hl_build_sdp_query_cfm
   2822  *
   2823  * Description   This function builds the SDP query indication event data
   2824  *
   2825  * Returns      None
   2826  *
   2827  ******************************************************************************/
   2828 void bta_hl_build_sdp_query_cfm(tBTA_HL* p_evt_data, uint8_t app_id,
   2829                                 tBTA_HL_APP_HANDLE app_handle,
   2830                                 const RawAddress& bd_addr, tBTA_HL_SDP* p_sdp,
   2831                                 tBTA_HL_STATUS status)
   2832 
   2833 {
   2834   APPL_TRACE_DEBUG("bta_hl_build_sdp_query_cfm: app_id = %d, app_handle=%d",
   2835                    app_id, app_handle);
   2836   p_evt_data->sdp_query_cfm.app_id = app_id;
   2837   p_evt_data->sdp_query_cfm.app_handle = app_handle;
   2838   p_evt_data->sdp_query_cfm.bd_addr = bd_addr;
   2839   p_evt_data->sdp_query_cfm.p_sdp = p_sdp;
   2840   p_evt_data->sdp_query_cfm.status = status;
   2841 }
   2842 
   2843 /*******************************************************************************
   2844  *
   2845  * Function      bta_hl_build_delete_mdl_cfm
   2846  *
   2847  * Description   This function builds the delete MDL confirmation event data
   2848  *
   2849  * Returns      None
   2850  *
   2851  ******************************************************************************/
   2852 void bta_hl_build_delete_mdl_cfm(tBTA_HL* p_evt_data,
   2853                                  tBTA_HL_APP_HANDLE app_handle,
   2854                                  tBTA_HL_MCL_HANDLE mcl_handle,
   2855                                  tBTA_HL_MDL_ID mdl_id, tBTA_HL_STATUS status)
   2856 
   2857 {
   2858   p_evt_data->delete_mdl_cfm.mcl_handle = mcl_handle;
   2859   p_evt_data->delete_mdl_cfm.app_handle = app_handle;
   2860   p_evt_data->delete_mdl_cfm.mdl_id = mdl_id;
   2861   p_evt_data->delete_mdl_cfm.status = status;
   2862 }
   2863 
   2864 /*******************************************************************************
   2865  *
   2866  * Function      bta_hl_build_echo_test_cfm
   2867  *
   2868  * Description   This function builds the echo test confirmation event data
   2869  *
   2870  * Returns      None
   2871  *
   2872  ******************************************************************************/
   2873 void bta_hl_build_echo_test_cfm(tBTA_HL* p_evt_data,
   2874                                 tBTA_HL_APP_HANDLE app_handle,
   2875                                 tBTA_HL_MCL_HANDLE mcl_handle,
   2876                                 tBTA_HL_STATUS status) {
   2877   p_evt_data->echo_test_cfm.mcl_handle = mcl_handle;
   2878   p_evt_data->echo_test_cfm.app_handle = app_handle;
   2879   p_evt_data->echo_test_cfm.status = status;
   2880 }
   2881 
   2882 /*****************************************************************************
   2883  *  Debug Functions
   2884  ****************************************************************************/
   2885 #if (BTA_HL_DEBUG == TRUE)
   2886 
   2887 /*******************************************************************************
   2888  *
   2889  * Function         bta_hl_status_code
   2890  *
   2891  * Description      get the status string pointer
   2892  *
   2893  * Returns          char * - status string pointer
   2894  *
   2895  ******************************************************************************/
   2896 const char* bta_hl_status_code(tBTA_HL_STATUS status) {
   2897   switch (status) {
   2898     case BTA_HL_STATUS_OK:
   2899       return "BTA_HL_STATUS_OK";
   2900     case BTA_HL_STATUS_FAIL:
   2901       return "BTA_HL_STATUS_FAIL";
   2902     case BTA_HL_STATUS_ABORTED:
   2903       return "BTA_HL_STATUS_ABORTED";
   2904     case BTA_HL_STATUS_NO_RESOURCE:
   2905       return "BTA_HL_STATUS_NO_RESOURCE";
   2906     case BTA_HL_STATUS_LAST_ITEM:
   2907       return "BTA_HL_STATUS_LAST_ITEM";
   2908     case BTA_HL_STATUS_DUPLICATE_APP_ID:
   2909       return "BTA_HL_STATUS_DUPLICATE_APP_ID";
   2910     case BTA_HL_STATUS_INVALID_APP_HANDLE:
   2911       return "BTA_HL_STATUS_INVALID_APP_HANDLE";
   2912     case BTA_HL_STATUS_INVALID_MCL_HANDLE:
   2913       return "BTA_HL_STATUS_INVALID_MCL_HANDLE";
   2914     case BTA_HL_STATUS_MCAP_REG_FAIL:
   2915       return "BTA_HL_STATUS_MCAP_REG_FAIL";
   2916     case BTA_HL_STATUS_MDEP_CO_FAIL:
   2917       return "BTA_HL_STATUS_MDEP_CO_FAIL";
   2918     case BTA_HL_STATUS_ECHO_CO_FAIL:
   2919       return "BTA_HL_STATUS_ECHO_CO_FAIL";
   2920     case BTA_HL_STATUS_MDL_CFG_CO_FAIL:
   2921       return "BTA_HL_STATUS_MDL_CFG_CO_FAIL";
   2922     case BTA_HL_STATUS_SDP_NO_RESOURCE:
   2923       return "BTA_HL_STATUS_SDP_NO_RESOURCE";
   2924     case BTA_HL_STATUS_SDP_FAIL:
   2925       return "BTA_HL_STATUS_SDP_FAIL";
   2926     case BTA_HL_STATUS_NO_CCH:
   2927       return "BTA_HL_STATUS_NO_CCH";
   2928     case BTA_HL_STATUS_NO_MCL:
   2929       return "BTA_HL_STATUS_NO_MCL";
   2930 
   2931     case BTA_HL_STATUS_NO_FIRST_RELIABLE:
   2932       return "BTA_HL_STATUS_NO_FIRST_RELIABLE";
   2933     case BTA_HL_STATUS_INVALID_DCH_CFG:
   2934       return "BTA_HL_STATUS_INVALID_DCH_CFG";
   2935     case BTA_HL_STATUS_INVALID_BD_ADDR:
   2936       return "BTA_HL_STATUS_INVALID_BD_ADDR";
   2937     case BTA_HL_STATUS_INVALID_RECONNECT_CFG:
   2938       return "BTA_HL_STATUS_INVALID_RECONNECT_CFG";
   2939     case BTA_HL_STATUS_ECHO_TEST_BUSY:
   2940       return "BTA_HL_STATUS_ECHO_TEST_BUSY";
   2941     case BTA_HL_STATUS_INVALID_LOCAL_MDEP_ID:
   2942       return "BTA_HL_STATUS_INVALID_LOCAL_MDEP_ID";
   2943     case BTA_HL_STATUS_INVALID_MDL_ID:
   2944       return "BTA_HL_STATUS_INVALID_MDL_ID";
   2945     case BTA_HL_STATUS_NO_MDL_ID_FOUND:
   2946       return "BTA_HL_STATUS_NO_MDL_ID_FOUND";
   2947     case BTA_HL_STATUS_DCH_BUSY:
   2948       return "BTA_HL_STATUS_DCH_BUSY";
   2949     default:
   2950       return "Unknown status code";
   2951   }
   2952 }
   2953 /*******************************************************************************
   2954  *
   2955  * Function         bta_hl_evt_code
   2956  *
   2957  * Description      Maps HL event code to the corresponding event string
   2958  *
   2959  * Returns          string pointer for the associated event name
   2960  *
   2961  ******************************************************************************/
   2962 const char* bta_hl_evt_code(tBTA_HL_INT_EVT evt_code) {
   2963   switch (evt_code) {
   2964     case BTA_HL_CCH_OPEN_EVT:
   2965       return "BTA_HL_CCH_OPEN_EVT";
   2966     case BTA_HL_CCH_SDP_OK_EVT:
   2967       return "BTA_HL_CCH_SDP_OK_EVT";
   2968     case BTA_HL_CCH_SDP_FAIL_EVT:
   2969       return "BTA_HL_CCH_SDP_FAIL_EVT";
   2970     case BTA_HL_MCA_CONNECT_IND_EVT:
   2971       return "BTA_HL_MCA_CONNECT_IND_EVT";
   2972     case BTA_HL_MCA_DISCONNECT_IND_EVT:
   2973       return "BTA_HL_MCA_DISCONNECT_IND_EVT";
   2974 
   2975     case BTA_HL_CCH_CLOSE_EVT:
   2976       return "BTA_HL_CCH_CLOSE_EVT";
   2977     case BTA_HL_CCH_CLOSE_CMPL_EVT:
   2978       return "BTA_HL_CCH_CLOSE_CMPL_EVT";
   2979     case BTA_HL_DCH_OPEN_EVT:
   2980       return "BTA_HL_DCH_OPEN_EVT";
   2981     case BTA_HL_MCA_CREATE_IND_EVT:
   2982       return "BTA_HL_MCA_CREATE_IND_EVT";
   2983     case BTA_HL_MCA_CREATE_CFM_EVT:
   2984       return "BTA_HL_MCA_CREATE_CFM_EVT";
   2985     case BTA_HL_MCA_OPEN_IND_EVT:
   2986       return "BTA_HL_MCA_OPEN_IND_EVT";
   2987     case BTA_HL_MCA_OPEN_CFM_EVT:
   2988       return "BTA_HL_MCA_OPEN_CFM_EVT";
   2989     case BTA_HL_DCH_CLOSE_EVT:
   2990       return "BTA_HL_DCH_CLOSE_EVT";
   2991     case BTA_HL_MCA_CLOSE_IND_EVT:
   2992       return "BTA_HL_MCA_CLOSE_IND_EVT";
   2993     case BTA_HL_MCA_CLOSE_CFM_EVT:
   2994       return "BTA_HL_MCA_CLOSE_CFM_EVT";
   2995     case BTA_HL_API_SEND_DATA_EVT:
   2996       return "BTA_HL_API_SEND_DATA_EVT";
   2997     case BTA_HL_MCA_RCV_DATA_EVT:
   2998       return "BTA_HL_MCA_RCV_DATA_EVT";
   2999     case BTA_HL_DCH_CLOSE_CMPL_EVT:
   3000       return "BTA_HL_DCH_CLOSE_CMPL_EVT";
   3001 
   3002     case BTA_HL_API_ENABLE_EVT:
   3003       return "BTA_HL_API_ENABLE_EVT";
   3004     case BTA_HL_API_DISABLE_EVT:
   3005       return "BTA_HL_API_DISABLE_EVT";
   3006     case BTA_HL_API_UPDATE_EVT:
   3007       return "BTA_HL_API_UPDATE_EVT";
   3008     case BTA_HL_API_REGISTER_EVT:
   3009       return "BTA_HL_API_REGISTER_EVT";
   3010     case BTA_HL_API_DEREGISTER_EVT:
   3011       return "BTA_HL_API_DEREGISTER_EVT";
   3012 
   3013     case BTA_HL_API_CCH_OPEN_EVT:
   3014       return "BTA_HL_API_CCH_OPEN_EVT";
   3015 
   3016     case BTA_HL_API_CCH_CLOSE_EVT:
   3017       return "BTA_HL_API_CCH_CLOSE_EVT";
   3018     case BTA_HL_API_DCH_OPEN_EVT:
   3019       return "BTA_HL_API_DCH_OPEN_EVT";
   3020 
   3021     case BTA_HL_API_DCH_RECONNECT_EVT:
   3022       return "BTA_HL_API_DCH_RECONNECT_EVT";
   3023     case BTA_HL_API_DCH_CLOSE_EVT:
   3024       return "BTA_HL_API_DCH_CLOSE_EVT";
   3025     case BTA_HL_API_DELETE_MDL_EVT:
   3026       return "BTA_HL_API_DELETE_MDL_EVT";
   3027     case BTA_HL_API_DCH_ABORT_EVT:
   3028       return "BTA_HL_API_DCH_ABORT_EVT";
   3029 
   3030     case BTA_HL_DCH_RECONNECT_EVT:
   3031       return "BTA_HL_DCH_RECONNECT_EVT";
   3032     case BTA_HL_DCH_SDP_INIT_EVT:
   3033       return "BTA_HL_DCH_SDP_INIT_EVT";
   3034     case BTA_HL_DCH_SDP_FAIL_EVT:
   3035       return "BTA_HL_DCH_SDP_FAIL_EVT";
   3036     case BTA_HL_API_DCH_ECHO_TEST_EVT:
   3037       return "BTA_HL_API_DCH_ECHO_TEST_EVT";
   3038     case BTA_HL_DCH_CLOSE_ECHO_TEST_EVT:
   3039       return "BTA_HL_DCH_CLOSE_ECHO_TEST_EVT";
   3040     case BTA_HL_MCA_RECONNECT_IND_EVT:
   3041       return "BTA_HL_MCA_RECONNECT_IND_EVT";
   3042     case BTA_HL_MCA_RECONNECT_CFM_EVT:
   3043       return "BTA_HL_MCA_RECONNECT_CFM_EVT";
   3044     case BTA_HL_API_DCH_CREATE_RSP_EVT:
   3045       return "BTA_HL_API_DCH_CREATE_RSP_EVT";
   3046     case BTA_HL_DCH_ABORT_EVT:
   3047       return "BTA_HL_DCH_ABORT_EVT";
   3048     case BTA_HL_MCA_ABORT_IND_EVT:
   3049       return "BTA_HL_MCA_ABORT_IND_EVT";
   3050     case BTA_HL_MCA_ABORT_CFM_EVT:
   3051       return "BTA_HL_MCA_ABORT_CFM_EVT";
   3052     case BTA_HL_MCA_DELETE_IND_EVT:
   3053       return "BTA_HL_MCA_DELETE_IND_EVT";
   3054     case BTA_HL_MCA_DELETE_CFM_EVT:
   3055       return "BTA_HL_MCA_DELETE_CFM_EVT";
   3056     case BTA_HL_MCA_CONG_CHG_EVT:
   3057       return "BTA_HL_MCA_CONG_CHG_EVT";
   3058     case BTA_HL_CI_GET_TX_DATA_EVT:
   3059       return "BTA_HL_CI_GET_TX_DATA_EVT";
   3060     case BTA_HL_CI_PUT_RX_DATA_EVT:
   3061       return "BTA_HL_CI_PUT_RX_DATA_EVT";
   3062     case BTA_HL_CI_GET_ECHO_DATA_EVT:
   3063       return "BTA_HL_CI_GET_ECHO_DATA_EVT";
   3064     case BTA_HL_DCH_ECHO_TEST_EVT:
   3065       return "BTA_HL_DCH_ECHO_TEST_EVT";
   3066     case BTA_HL_CI_PUT_ECHO_DATA_EVT:
   3067       return "BTA_HL_CI_PUT_ECHO_DATA_EVT";
   3068     case BTA_HL_API_SDP_QUERY_EVT:
   3069       return "BTA_HL_API_SDP_QUERY_EVT";
   3070     case BTA_HL_SDP_QUERY_OK_EVT:
   3071       return "BTA_HL_SDP_QUERY_OK_EVT";
   3072     case BTA_HL_SDP_QUERY_FAIL_EVT:
   3073       return "BTA_HL_SDP_QUERY_FAIL_EVT";
   3074     case BTA_HL_MCA_RSP_TOUT_IND_EVT:
   3075       return "BTA_HL_MCA_RSP_TOUT_IND_EVT";
   3076 
   3077     default:
   3078       return "Unknown HL event code";
   3079   }
   3080 }
   3081 
   3082 #endif  /* Debug Functions */
   3083 #endif  // HL_INCLUDED
   3084