Home | History | Annotate | Download | only in hl
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 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, BD_ADDR 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         (!memcmp(bta_hl_cb.acb[app_idx].mcb[i].bd_addr, p_bd_addr,
   1037                  BD_ADDR_LEN))) {
   1038       found = true;
   1039       *p_mcl_idx = i;
   1040       break;
   1041     }
   1042   }
   1043 
   1044 #if (BTA_HL_DEBUG == TRUE)
   1045   if (!found) {
   1046     APPL_TRACE_DEBUG("bta_hl_find_mcl_idx found=%d idx=%d", found, i);
   1047   }
   1048 #endif
   1049   return found;
   1050 }
   1051 
   1052 /*******************************************************************************
   1053  *
   1054  * Function      bta_hl_find_mdl_idx_using_handle
   1055  *
   1056  * Description  This function finds the MDL control block index based on
   1057  *              the MDL handle
   1058  *
   1059  * Returns      bool true-found
   1060  *
   1061  ******************************************************************************/
   1062 bool bta_hl_find_mdl_idx_using_handle(tBTA_HL_MDL_HANDLE mdl_handle,
   1063                                       uint8_t* p_app_idx, uint8_t* p_mcl_idx,
   1064                                       uint8_t* p_mdl_idx) {
   1065   tBTA_HL_APP_CB* p_acb;
   1066   tBTA_HL_MCL_CB* p_mcb;
   1067   tBTA_HL_MDL_CB* p_dcb;
   1068   bool found = false;
   1069   uint8_t i, j, k;
   1070 
   1071   for (i = 0; i < BTA_HL_NUM_APPS; i++) {
   1072     p_acb = BTA_HL_GET_APP_CB_PTR(i);
   1073     if (p_acb->in_use) {
   1074       for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
   1075         p_mcb = BTA_HL_GET_MCL_CB_PTR(i, j);
   1076         if (p_mcb->in_use) {
   1077           for (k = 0; k < BTA_HL_NUM_MDLS_PER_MCL; k++) {
   1078             p_dcb = BTA_HL_GET_MDL_CB_PTR(i, j, k);
   1079             if (p_dcb->in_use) {
   1080               if (p_dcb->mdl_handle == mdl_handle) {
   1081                 found = true;
   1082                 *p_app_idx = i;
   1083                 *p_mcl_idx = j;
   1084                 *p_mdl_idx = k;
   1085                 break;
   1086               }
   1087             }
   1088           }
   1089         }
   1090       }
   1091     }
   1092   }
   1093 
   1094 #if (BTA_HL_DEBUG == TRUE)
   1095   if (!found) {
   1096     APPL_TRACE_DEBUG(
   1097         "bta_hl_find_mdl_idx_using_handle found=%d mdl_handle=%d  ", found,
   1098         mdl_handle);
   1099   }
   1100 #endif
   1101   return found;
   1102 }
   1103 /*******************************************************************************
   1104  *
   1105  * Function      bta_hl_is_the_first_reliable_existed
   1106  *
   1107  * Description  This function checks whether the first reliable DCH channel
   1108  *              has been setup on the MCL or not
   1109  *
   1110  * Returns      bool - true exist
   1111  *                        false does not exist
   1112  *
   1113  ******************************************************************************/
   1114 bool bta_hl_is_the_first_reliable_existed(uint8_t app_idx, uint8_t mcl_idx) {
   1115   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
   1116   bool is_existed = false;
   1117   uint8_t i;
   1118 
   1119   for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
   1120     if (p_mcb->mdl[i].in_use && p_mcb->mdl[i].is_the_first_reliable) {
   1121       is_existed = true;
   1122       break;
   1123     }
   1124   }
   1125 
   1126 #if (BTA_HL_DEBUG == TRUE)
   1127   APPL_TRACE_DEBUG("bta_hl_is_the_first_reliable_existed is_existed=%d  ",
   1128                    is_existed);
   1129 #endif
   1130   return is_existed;
   1131 }
   1132 
   1133 /*******************************************************************************
   1134  *
   1135  * Function      bta_hl_find_non_active_mdl_cfg
   1136  *
   1137  * Description  This function finds a valid MDL configiration index and this
   1138  *              MDL ID is not active
   1139  *
   1140  * Returns      bool - true found
   1141  *                        false not found
   1142  *
   1143  ******************************************************************************/
   1144 bool bta_hl_find_non_active_mdl_cfg(uint8_t app_idx, uint8_t start_mdl_cfg_idx,
   1145                                     uint8_t* p_mdl_cfg_idx) {
   1146   tBTA_HL_MCL_CB* p_mcb;
   1147   tBTA_HL_MDL_CB* p_dcb;
   1148   tBTA_HL_MDL_CFG* p_mdl;
   1149   bool mdl_in_use;
   1150   bool found = false;
   1151   uint8_t i, j, k;
   1152 
   1153   for (i = start_mdl_cfg_idx; i < BTA_HL_NUM_MDL_CFGS; i++) {
   1154     mdl_in_use = false;
   1155     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
   1156     for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
   1157       p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, j);
   1158       if (p_mcb->in_use &&
   1159           !memcmp(p_mdl->peer_bd_addr, p_mcb->bd_addr, BD_ADDR_LEN)) {
   1160         for (k = 0; k < BTA_HL_NUM_MDLS_PER_MCL; k++) {
   1161           p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, j, k);
   1162 
   1163           if (p_dcb->in_use && p_mdl->mdl_id == p_dcb->mdl_id) {
   1164             mdl_in_use = true;
   1165             break;
   1166           }
   1167         }
   1168       }
   1169 
   1170       if (mdl_in_use) {
   1171         break;
   1172       }
   1173     }
   1174 
   1175     if (!mdl_in_use) {
   1176       *p_mdl_cfg_idx = i;
   1177       found = true;
   1178       break;
   1179     }
   1180   }
   1181 
   1182   return found;
   1183 }
   1184 
   1185 /*******************************************************************************
   1186  *
   1187  * Function      bta_hl_find_mdl_cfg_idx
   1188  *
   1189  * Description  This function finds an available MDL configuration index
   1190  *
   1191  * Returns      bool - true found
   1192  *                        false not found
   1193  *
   1194  ******************************************************************************/
   1195 bool bta_hl_find_avail_mdl_cfg_idx(uint8_t app_idx, UNUSED_ATTR uint8_t mcl_idx,
   1196                                    uint8_t* p_mdl_cfg_idx) {
   1197   tBTA_HL_MDL_CFG *p_mdl, *p_mdl1, *p_mdl2;
   1198   uint8_t i;
   1199   bool found = false;
   1200   uint8_t first_mdl_cfg_idx, second_mdl_cfg_idx, older_mdl_cfg_idx;
   1201   bool done;
   1202 
   1203   for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
   1204     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
   1205     if (!p_mdl->active) {
   1206       /* found an unused space to store mdl cfg*/
   1207       found = true;
   1208       *p_mdl_cfg_idx = i;
   1209       break;
   1210     }
   1211   }
   1212 
   1213   if (!found) {
   1214     /* all available mdl cfg spaces are in use so we need to find the mdl cfg
   1215     which is
   1216     not currently in use and has the the oldest time stamp to remove*/
   1217 
   1218     found = true;
   1219     if (bta_hl_find_non_active_mdl_cfg(app_idx, 0, &first_mdl_cfg_idx)) {
   1220       if (bta_hl_find_non_active_mdl_cfg(
   1221               app_idx, (uint8_t)(first_mdl_cfg_idx + 1), &second_mdl_cfg_idx)) {
   1222         done = false;
   1223         while (!done) {
   1224           p_mdl1 = BTA_HL_GET_MDL_CFG_PTR(app_idx, first_mdl_cfg_idx);
   1225           p_mdl2 = BTA_HL_GET_MDL_CFG_PTR(app_idx, second_mdl_cfg_idx);
   1226 
   1227           if (p_mdl1->time < p_mdl2->time) {
   1228             older_mdl_cfg_idx = first_mdl_cfg_idx;
   1229           } else {
   1230             older_mdl_cfg_idx = second_mdl_cfg_idx;
   1231           }
   1232 
   1233           if (bta_hl_find_non_active_mdl_cfg(app_idx,
   1234                                              (uint8_t)(second_mdl_cfg_idx + 1),
   1235                                              &second_mdl_cfg_idx)) {
   1236             first_mdl_cfg_idx = older_mdl_cfg_idx;
   1237           } else {
   1238             done = true;
   1239           }
   1240         }
   1241 
   1242         *p_mdl_cfg_idx = older_mdl_cfg_idx;
   1243 
   1244       } else {
   1245         *p_mdl_cfg_idx = first_mdl_cfg_idx;
   1246       }
   1247 
   1248     } else {
   1249       found = false;
   1250     }
   1251   }
   1252 
   1253 #if (BTA_HL_DEBUG == TRUE)
   1254   if (!found) {
   1255     APPL_TRACE_DEBUG("bta_hl_find_avail_mdl_cfg_idx found=%d mdl_cfg_idx=%d ",
   1256                      found, *p_mdl_cfg_idx);
   1257   }
   1258 #endif
   1259 
   1260   return found;
   1261 }
   1262 
   1263 /*******************************************************************************
   1264  *
   1265  * Function      bta_hl_find_mdl_cfg_idx
   1266  *
   1267  * Description  This function finds the MDL configuration index based on
   1268  *              the MDL ID
   1269  *
   1270  * Returns      bool - true found
   1271  *                        false not found
   1272  *
   1273  ******************************************************************************/
   1274 bool bta_hl_find_mdl_cfg_idx(uint8_t app_idx, uint8_t mcl_idx,
   1275                              tBTA_HL_MDL_ID mdl_id, uint8_t* p_mdl_cfg_idx) {
   1276   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
   1277   tBTA_HL_MDL_CFG* p_mdl;
   1278   uint8_t i;
   1279   bool found = false;
   1280 
   1281   *p_mdl_cfg_idx = 0;
   1282   for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
   1283     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
   1284     if (p_mdl->active)
   1285       APPL_TRACE_DEBUG("bta_hl_find_mdl_cfg_idx: mdl_id =%d, p_mdl->mdl_id=%d",
   1286                        mdl_id, p_mdl->mdl_id);
   1287     if (p_mdl->active &&
   1288         (!memcmp(p_mcb->bd_addr, p_mdl->peer_bd_addr, BD_ADDR_LEN)) &&
   1289         (p_mdl->mdl_id == mdl_id)) {
   1290       found = true;
   1291       *p_mdl_cfg_idx = i;
   1292       break;
   1293     }
   1294   }
   1295 
   1296 #if (BTA_HL_DEBUG == TRUE)
   1297   if (!found) {
   1298     APPL_TRACE_DEBUG("bta_hl_find_mdl_cfg_idx found=%d mdl_cfg_idx=%d ", found,
   1299                      i);
   1300   }
   1301 #endif
   1302 
   1303   return found;
   1304 }
   1305 
   1306 /*******************************************************************************
   1307  *
   1308  * Function      bta_hl_get_cur_time
   1309  *
   1310  * Description  This function get the cuurent time value
   1311  *
   1312  * Returns      bool - true found
   1313  *                        false not found
   1314  *
   1315  ******************************************************************************/
   1316 bool bta_hl_get_cur_time(uint8_t app_idx, uint8_t* p_cur_time) {
   1317   tBTA_HL_MDL_CFG* p_mdl;
   1318   uint8_t i, j, time_latest, time;
   1319   bool found = false, result = true;
   1320 
   1321   for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
   1322     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
   1323     if (p_mdl->active) {
   1324       found = true;
   1325       time_latest = p_mdl->time;
   1326       for (j = (i + 1); j < BTA_HL_NUM_MDL_CFGS; j++) {
   1327         p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, j);
   1328         if (p_mdl->active) {
   1329           time = p_mdl->time;
   1330           if (time > time_latest) {
   1331             time_latest = time;
   1332           }
   1333         }
   1334       }
   1335       break;
   1336     }
   1337   }
   1338 
   1339   if (found) {
   1340     if (time_latest < BTA_HL_MAX_TIME) {
   1341       *p_cur_time = time_latest + 1;
   1342     } else {
   1343       /* need to wrap around */
   1344       result = false;
   1345     }
   1346   } else {
   1347     *p_cur_time = BTA_HL_MIN_TIME;
   1348   }
   1349 
   1350 #if (BTA_HL_DEBUG == TRUE)
   1351   if (!result) {
   1352     APPL_TRACE_DEBUG("bta_hl_get_cur_time result=%s cur_time=%d",
   1353                      (result ? "OK" : "FAIL"), *p_cur_time);
   1354   }
   1355 #endif
   1356 
   1357   return result;
   1358 }
   1359 
   1360 /*******************************************************************************
   1361  *
   1362  * Function      bta_hl_sort_cfg_time_idx
   1363  *
   1364  * Description  This function sort the mdl configuration idx stored in array a
   1365  *              based on decending time value
   1366  *
   1367  * Returns      bool - true found
   1368  *                        false not found
   1369  *
   1370  ******************************************************************************/
   1371 void bta_hl_sort_cfg_time_idx(uint8_t app_idx, uint8_t* a, uint8_t n) {
   1372   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   1373   uint8_t temp_time, temp_idx;
   1374   int16_t i, j;
   1375   for (i = 1; i < n; ++i) {
   1376     temp_idx = a[i];
   1377     temp_time = p_acb->mdl_cfg[temp_idx].time;
   1378     j = i - 1;
   1379     while ((j >= 0) && (temp_time < p_acb->mdl_cfg[a[j]].time)) {
   1380       a[j + 1] = a[j];
   1381       --j;
   1382     }
   1383     a[j + 1] = temp_idx;
   1384   }
   1385 }
   1386 
   1387 /*******************************************************************************
   1388  *
   1389  * Function      bta_hl_compact_mdl_cfg_time
   1390  *
   1391  * Description  This function finds the MDL configuration index based on
   1392  *              the MDL ID
   1393  *
   1394  * Returns      bool - true found
   1395  *                        false not found
   1396  *
   1397  ******************************************************************************/
   1398 void bta_hl_compact_mdl_cfg_time(uint8_t app_idx, uint8_t mdep_id) {
   1399   tBTA_HL_MDL_CFG* p_mdl;
   1400   uint8_t i, time_min, cnt = 0;
   1401   uint8_t s_arr[BTA_HL_NUM_MDL_CFGS];
   1402 
   1403   for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
   1404     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
   1405     if (p_mdl->active) {
   1406       s_arr[cnt] = i;
   1407       cnt++;
   1408     }
   1409   }
   1410 
   1411 #if (BTA_HL_DEBUG == TRUE)
   1412   APPL_TRACE_DEBUG("bta_hl_compact_mdl_cfg_time cnt=%d ", cnt);
   1413 #endif
   1414 
   1415   if (cnt) {
   1416     bta_hl_sort_cfg_time_idx(app_idx, s_arr, cnt);
   1417     time_min = BTA_HL_MIN_TIME;
   1418     for (i = 0; i < cnt; i++) {
   1419       p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, s_arr[i]);
   1420       p_mdl->time = time_min + i;
   1421       bta_hl_co_save_mdl(mdep_id, s_arr[i], p_mdl);
   1422     }
   1423   }
   1424 }
   1425 
   1426 /*******************************************************************************
   1427  *
   1428  * Function      bta_hl_is_mdl_exsit_in_mcl
   1429  *
   1430  * Description  This function checks whether the MDL ID
   1431  *              has already existed in teh MCL or not
   1432  *
   1433  * Returns      bool - true exist
   1434  *                        false does not exist
   1435  *
   1436  ******************************************************************************/
   1437 bool bta_hl_is_mdl_exsit_in_mcl(uint8_t app_idx, BD_ADDR bd_addr,
   1438                                 tBTA_HL_MDL_ID mdl_id) {
   1439   tBTA_HL_MDL_CFG* p_mdl;
   1440   bool found = false;
   1441   uint8_t i;
   1442 
   1443   for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
   1444     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
   1445     if (p_mdl->active && !memcmp(p_mdl->peer_bd_addr, bd_addr, BD_ADDR_LEN)) {
   1446       if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) {
   1447         if (p_mdl->mdl_id == mdl_id) {
   1448           found = true;
   1449           break;
   1450         }
   1451       } else {
   1452         found = true;
   1453         break;
   1454       }
   1455     }
   1456   }
   1457 
   1458   return found;
   1459 }
   1460 
   1461 /*******************************************************************************
   1462  *
   1463  * Function      bta_hl_delete_mdl_cfg
   1464  *
   1465  * Description  This function delete the specified MDL ID
   1466  *
   1467  * Returns      bool - true Success
   1468  *                        false Failed
   1469  *
   1470  ******************************************************************************/
   1471 bool bta_hl_delete_mdl_cfg(uint8_t app_idx, BD_ADDR bd_addr,
   1472                            tBTA_HL_MDL_ID mdl_id) {
   1473   tBTA_HL_MDL_CFG* p_mdl;
   1474   bool success = false;
   1475   uint8_t i;
   1476 
   1477   for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
   1478     p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
   1479     if (p_mdl->active && !memcmp(p_mdl->peer_bd_addr, bd_addr, BD_ADDR_LEN)) {
   1480       if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) {
   1481         if (p_mdl->mdl_id == mdl_id) {
   1482           bta_hl_co_delete_mdl(p_mdl->local_mdep_id, i);
   1483           memset(p_mdl, 0, sizeof(tBTA_HL_MDL_CFG));
   1484           success = true;
   1485           break;
   1486         }
   1487       } else {
   1488         bta_hl_co_delete_mdl(p_mdl->local_mdep_id, i);
   1489         memset(p_mdl, 0, sizeof(tBTA_HL_MDL_CFG));
   1490         success = true;
   1491       }
   1492     }
   1493   }
   1494 
   1495   return success;
   1496 }
   1497 
   1498 /*******************************************************************************
   1499  *
   1500  * Function      bta_hl_is_mdl_value_valid
   1501  *
   1502  *
   1503  * Description  This function checks the specified MDL ID is in valid range.
   1504  *
   1505  * Returns      bool - true Success
   1506  *                        false Failed
   1507  *
   1508  * note:   mdl_id range   0x0000 reserved,
   1509  *                        0x0001-oxFEFF dynamic range,
   1510  *                        0xFF00-0xFFFE reserved,
   1511  *                        0xFFFF indicates all MDLs (for delete operation only)
   1512  *
   1513  ******************************************************************************/
   1514 bool bta_hl_is_mdl_value_valid(tBTA_HL_MDL_ID mdl_id) {
   1515   bool status = true;
   1516 
   1517   if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) {
   1518     if (mdl_id != 0) {
   1519       if (mdl_id > BTA_HL_MAX_MDL_VAL) {
   1520         status = false;
   1521       }
   1522     } else {
   1523       status = false;
   1524     }
   1525   }
   1526 
   1527   return status;
   1528 }
   1529 
   1530 /*******************************************************************************
   1531  *
   1532  * Function      bta_hl_find_mdep_cfg_idx
   1533  *
   1534  * Description  This function finds the MDEP configuration index based
   1535  *                on the local MDEP ID
   1536  *
   1537  * Returns      bool - true found
   1538  *                        false not found
   1539  *
   1540  ******************************************************************************/
   1541 bool bta_hl_find_mdep_cfg_idx(uint8_t app_idx, tBTA_HL_MDEP_ID local_mdep_id,
   1542                               uint8_t* p_mdep_cfg_idx) {
   1543   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   1544   tBTA_HL_SUP_FEATURE* p_sup_feature = &p_acb->sup_feature;
   1545   bool found = false;
   1546   uint8_t i;
   1547 
   1548   for (i = 0; i < p_sup_feature->num_of_mdeps; i++) {
   1549     if (p_sup_feature->mdep[i].mdep_id == local_mdep_id) {
   1550       found = true;
   1551       *p_mdep_cfg_idx = i;
   1552       break;
   1553     }
   1554   }
   1555 
   1556 #if (BTA_HL_DEBUG == TRUE)
   1557   if (!found) {
   1558     APPL_TRACE_DEBUG(
   1559         "bta_hl_find_mdep_cfg_idx found=%d mdep_idx=%d local_mdep_id=%d ",
   1560         found, i, local_mdep_id);
   1561   }
   1562 #endif
   1563   return found;
   1564 }
   1565 
   1566 /*******************************************************************************
   1567  *
   1568  * Function      bta_hl_find_rxtx_apdu_size
   1569  *
   1570  * Description  This function finds the maximum APDU rx and tx sizes based on
   1571  *              the MDEP configuration data
   1572  *
   1573  * Returns      void
   1574  *
   1575  ******************************************************************************/
   1576 void bta_hl_find_rxtx_apdu_size(uint8_t app_idx, uint8_t mdep_cfg_idx,
   1577                                 uint16_t* p_rx_apu_size,
   1578                                 uint16_t* p_tx_apu_size) {
   1579   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   1580   tBTA_HL_MDEP_CFG* p_mdep_cfg;
   1581   uint8_t i;
   1582   uint16_t max_rx_apdu_size = 0, max_tx_apdu_size = 0;
   1583 
   1584   p_mdep_cfg = &p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg;
   1585 
   1586   for (i = 0; i < p_mdep_cfg->num_of_mdep_data_types; i++) {
   1587     if (max_rx_apdu_size < p_mdep_cfg->data_cfg[i].max_rx_apdu_size) {
   1588       max_rx_apdu_size = p_mdep_cfg->data_cfg[i].max_rx_apdu_size;
   1589     }
   1590 
   1591     if (max_tx_apdu_size < p_mdep_cfg->data_cfg[i].max_tx_apdu_size) {
   1592       max_tx_apdu_size = p_mdep_cfg->data_cfg[i].max_tx_apdu_size;
   1593     }
   1594   }
   1595 
   1596   *p_rx_apu_size = max_rx_apdu_size;
   1597   *p_tx_apu_size = max_tx_apdu_size;
   1598 
   1599 #if (BTA_HL_DEBUG == TRUE)
   1600   APPL_TRACE_DEBUG(
   1601       "bta_hl_find_rxtx_apdu_size max_rx_apdu_size=%d max_tx_apdu_size=%d ",
   1602       max_rx_apdu_size, max_tx_apdu_size);
   1603 #endif
   1604 }
   1605 
   1606 /*******************************************************************************
   1607  *
   1608  * Function      bta_hl_validate_peer_cfg
   1609  *
   1610  * Description  This function validates the peer DCH configuration
   1611  *
   1612  * Returns      bool - true validation is successful
   1613  *                        false validation failed
   1614  *
   1615  ******************************************************************************/
   1616 bool bta_hl_validate_peer_cfg(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
   1617                               tBTA_HL_MDEP_ID peer_mdep_id,
   1618                               tBTA_HL_MDEP_ROLE peer_mdep_role,
   1619                               uint8_t sdp_idx) {
   1620   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
   1621   tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
   1622   tBTA_HL_SDP_REC* p_rec;
   1623   bool peer_found = false;
   1624   uint8_t i;
   1625 
   1626   APPL_TRACE_DEBUG("bta_hl_validate_peer_cfg sdp_idx=%d app_idx %d", sdp_idx,
   1627                    app_idx);
   1628 
   1629   if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) {
   1630     return true;
   1631   }
   1632 
   1633   p_rec = &p_mcb->sdp.sdp_rec[sdp_idx];
   1634   for (i = 0; i < p_rec->num_mdeps; i++) {
   1635     APPL_TRACE_DEBUG("mdep_id %d peer_mdep_id %d", p_rec->mdep_cfg[i].mdep_id,
   1636                      peer_mdep_id);
   1637     APPL_TRACE_DEBUG("mdep_role %d peer_mdep_role %d",
   1638                      p_rec->mdep_cfg[i].mdep_role, peer_mdep_role)
   1639     if ((p_rec->mdep_cfg[i].mdep_id == peer_mdep_id) &&
   1640         (p_rec->mdep_cfg[i].mdep_role == peer_mdep_role)) {
   1641       peer_found = true;
   1642 
   1643       break;
   1644     }
   1645   }
   1646 
   1647 #if (BTA_HL_DEBUG == TRUE)
   1648   if (!peer_found) {
   1649     APPL_TRACE_DEBUG("bta_hl_validate_peer_cfg failed num_mdeps=%d",
   1650                      p_rec->num_mdeps);
   1651   }
   1652 #endif
   1653   return peer_found;
   1654 }
   1655 
   1656 /*******************************************************************************
   1657  *
   1658  * Function      bta_hl_chk_local_cfg
   1659  *
   1660  * Description  This function check whether the local DCH configuration is OK.
   1661  *
   1662  * Returns      tBTA_HL_STATUS - OK - local DCH configuration is OK
   1663  *                               NO_FIRST_RELIABLE - the streaming DCH
   1664  *                                                   configuration is not OK and
   1665  *                                                   it needs to use reliable
   1666  *                                                   DCH configuration
   1667  *
   1668  ******************************************************************************/
   1669 tBTA_HL_STATUS bta_hl_chk_local_cfg(uint8_t app_idx, uint8_t mcl_idx,
   1670                                     uint8_t mdep_cfg_idx,
   1671                                     tBTA_HL_DCH_CFG local_cfg) {
   1672   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   1673   tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
   1674 
   1675   if (mdep_cfg_idx &&
   1676       (p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg.mdep_role ==
   1677        BTA_HL_MDEP_ROLE_SOURCE) &&
   1678       (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) &&
   1679       (local_cfg != BTA_HL_DCH_CFG_RELIABLE)) {
   1680     status = BTA_HL_STATUS_NO_FIRST_RELIABLE;
   1681     APPL_TRACE_ERROR("BTA_HL_STATUS_INVALID_DCH_CFG");
   1682   }
   1683 
   1684   return status;
   1685 }
   1686 
   1687 /*******************************************************************************
   1688  *
   1689  * Function      bta_hl_validate_reconnect_params
   1690  *
   1691  * Description  This function validates the reconnect parameters
   1692  *
   1693  * Returns      bool - true validation is successful
   1694  *                        false validation failed
   1695  ******************************************************************************/
   1696 bool bta_hl_validate_reconnect_params(uint8_t app_idx, uint8_t mcl_idx,
   1697                                       tBTA_HL_API_DCH_RECONNECT* p_reconnect,
   1698                                       uint8_t* p_mdep_cfg_idx,
   1699                                       uint8_t* p_mdl_cfg_idx) {
   1700   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   1701   tBTA_HL_SUP_FEATURE* p_sup_feature = &p_acb->sup_feature;
   1702   uint8_t num_mdeps;
   1703   uint8_t mdl_cfg_idx;
   1704   bool local_mdep_id_found = false;
   1705   bool mdl_cfg_found = false;
   1706   bool status = false;
   1707   uint8_t i, in_use_mdl_idx = 0;
   1708 
   1709 #if (BTA_HL_DEBUG == TRUE)
   1710   APPL_TRACE_DEBUG("bta_hl_validate_reconnect_params  mdl_id=%d app_idx=%d",
   1711                    p_reconnect->mdl_id, app_idx);
   1712 #endif
   1713   if (bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, p_reconnect->mdl_id,
   1714                               &mdl_cfg_idx)) {
   1715     mdl_cfg_found = true;
   1716   }
   1717 
   1718 #if (BTA_HL_DEBUG == TRUE)
   1719   if (!mdl_cfg_found) {
   1720     APPL_TRACE_DEBUG("mdl_cfg_found not found");
   1721   }
   1722 #endif
   1723 
   1724   if (mdl_cfg_found) {
   1725     num_mdeps = p_sup_feature->num_of_mdeps;
   1726     for (i = 0; i < num_mdeps; i++) {
   1727       if (p_sup_feature->mdep[i].mdep_id ==
   1728           p_acb->mdl_cfg[mdl_cfg_idx].local_mdep_id) {
   1729         local_mdep_id_found = true;
   1730         *p_mdep_cfg_idx = i;
   1731         *p_mdl_cfg_idx = mdl_cfg_idx;
   1732         break;
   1733       }
   1734     }
   1735   }
   1736 
   1737 #if (BTA_HL_DEBUG == TRUE)
   1738   if (!local_mdep_id_found) {
   1739     APPL_TRACE_DEBUG("local_mdep_id not found");
   1740   }
   1741 #endif
   1742 
   1743   if (local_mdep_id_found) {
   1744     if (!bta_hl_find_mdl_idx(app_idx, mcl_idx, p_reconnect->mdl_id,
   1745                              &in_use_mdl_idx)) {
   1746       status = true;
   1747     } else {
   1748       APPL_TRACE_ERROR("mdl_id=%d is curreltly in use", p_reconnect->mdl_id);
   1749     }
   1750   }
   1751 
   1752 #if (BTA_HL_DEBUG == TRUE)
   1753   if (!status) {
   1754     APPL_TRACE_DEBUG(
   1755         "Reconnect validation failed local_mdep_id found=%d mdl_cfg_idx "
   1756         "found=%d in_use_mdl_idx=%d ",
   1757         local_mdep_id_found, mdl_cfg_found, in_use_mdl_idx);
   1758   }
   1759 #endif
   1760   return status;
   1761 }
   1762 
   1763 /*******************************************************************************
   1764  *
   1765  * Function      bta_hl_find_avail_mcl_idx
   1766  *
   1767  * Returns      bool - true found
   1768  *                        false not found
   1769  *
   1770  ******************************************************************************/
   1771 bool bta_hl_find_avail_mcl_idx(uint8_t app_idx, uint8_t* p_mcl_idx) {
   1772   bool found = false;
   1773   uint8_t i;
   1774 
   1775   for (i = 0; i < BTA_HL_NUM_MCLS; i++) {
   1776     if (!bta_hl_cb.acb[app_idx].mcb[i].in_use) {
   1777       found = true;
   1778       *p_mcl_idx = i;
   1779       break;
   1780     }
   1781   }
   1782 
   1783 #if (BTA_HL_DEBUG == TRUE)
   1784   if (!found) {
   1785     APPL_TRACE_DEBUG("bta_hl_find_avail_mcl_idx found=%d idx=%d", found, i);
   1786   }
   1787 #endif
   1788   return found;
   1789 }
   1790 
   1791 /*******************************************************************************
   1792  *
   1793  * Function      bta_hl_find_avail_mdl_idx
   1794  *
   1795  * Description  This function finds an available MDL control block index
   1796  *
   1797  * Returns      bool - true found
   1798  *                        false not found
   1799  *
   1800  ******************************************************************************/
   1801 bool bta_hl_find_avail_mdl_idx(uint8_t app_idx, uint8_t mcl_idx,
   1802                                uint8_t* p_mdl_idx) {
   1803   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
   1804   bool found = false;
   1805   uint8_t i;
   1806 
   1807   for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
   1808     if (!p_mcb->mdl[i].in_use) {
   1809       memset((void*)&p_mcb->mdl[i], 0, sizeof(tBTA_HL_MDL_CB));
   1810       found = true;
   1811       *p_mdl_idx = i;
   1812       break;
   1813     }
   1814   }
   1815 
   1816 #if (BTA_HL_DEBUG == TRUE)
   1817   if (!found) {
   1818     APPL_TRACE_DEBUG("bta_hl_find_avail_mdl_idx found=%d idx=%d", found, i);
   1819   }
   1820 #endif
   1821   return found;
   1822 }
   1823 
   1824 /*******************************************************************************
   1825  *
   1826  * Function      bta_hl_is_a_duplicate_id
   1827  *
   1828  * Description  This function finds the application has been used or not
   1829  *
   1830  * Returns      bool - true the app_id is a duplicate ID
   1831  *                        false not a duplicate ID
   1832  ******************************************************************************/
   1833 bool bta_hl_is_a_duplicate_id(uint8_t app_id) {
   1834   bool is_duplicate = false;
   1835   uint8_t i;
   1836 
   1837   for (i = 0; i < BTA_HL_NUM_APPS; i++) {
   1838     if (bta_hl_cb.acb[i].in_use && (bta_hl_cb.acb[i].app_id == app_id)) {
   1839       is_duplicate = true;
   1840 
   1841       break;
   1842     }
   1843   }
   1844 
   1845 #if (BTA_HL_DEBUG == TRUE)
   1846   if (is_duplicate) {
   1847     APPL_TRACE_DEBUG("bta_hl_is_a_duplicate_id app_id=%d is_duplicate=%d",
   1848                      app_id, is_duplicate);
   1849   }
   1850 #endif
   1851 
   1852   return is_duplicate;
   1853 }
   1854 
   1855 /*******************************************************************************
   1856  *
   1857  * Function      bta_hl_find_avail_app_idx
   1858  *
   1859  * Description  This function finds an available application control block index
   1860  *
   1861  * Returns      bool - true found
   1862  *                        false not found
   1863  *
   1864  ******************************************************************************/
   1865 bool bta_hl_find_avail_app_idx(uint8_t* p_idx) {
   1866   bool found = false;
   1867   uint8_t i;
   1868 
   1869   for (i = 0; i < BTA_HL_NUM_APPS; i++) {
   1870     if (!bta_hl_cb.acb[i].in_use) {
   1871       found = true;
   1872       *p_idx = i;
   1873       break;
   1874     }
   1875   }
   1876 
   1877 #if (BTA_HL_DEBUG == TRUE)
   1878   if (!found) {
   1879     APPL_TRACE_DEBUG("bta_hl_find_avail_app_idx found=%d app_idx=%d", found, i);
   1880   }
   1881 #endif
   1882   return found;
   1883 }
   1884 
   1885 /*******************************************************************************
   1886  *
   1887  * Function      bta_hl_app_update
   1888  *
   1889  * Description  This function registers an HDP application MCAP and DP
   1890  *
   1891  * Returns      tBTA_HL_STATUS -registration status
   1892  *
   1893  ******************************************************************************/
   1894 tBTA_HL_STATUS bta_hl_app_update(uint8_t app_id, bool is_register) {
   1895   tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
   1896   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(0);
   1897   tMCA_CS mca_cs;
   1898   uint8_t i, mdep_idx, num_of_mdeps;
   1899   uint8_t mdep_counter = 0;
   1900 
   1901 #if (BTA_HL_DEBUG == TRUE)
   1902   APPL_TRACE_DEBUG("bta_hl_app_update app_id=%d", app_id);
   1903 #endif
   1904 
   1905   if (is_register) {
   1906     if ((status == BTA_HL_STATUS_OK) &&
   1907         bta_hl_co_get_num_of_mdep(app_id, &num_of_mdeps)) {
   1908       for (i = 0; i < num_of_mdeps; i++) {
   1909         mca_cs.type = MCA_TDEP_DATA;
   1910         mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP;
   1911         mca_cs.p_data_cback = bta_hl_mcap_data_cback;
   1912         /* Find the first available mdep index, and create a MDL Endpoint */
   1913         // make a function later if needed
   1914         for (mdep_idx = 1; mdep_idx < BTA_HL_NUM_MDEPS; mdep_idx++) {
   1915           if (p_acb->sup_feature.mdep[mdep_idx].mdep_id == 0) {
   1916             break; /* We found an available index */
   1917           } else {
   1918             mdep_counter++;
   1919           }
   1920         }
   1921         /* If no available MDEPs, return error */
   1922         if (mdep_idx == BTA_HL_NUM_MDEPS) {
   1923           APPL_TRACE_ERROR("bta_hl_app_update: Out of MDEP IDs");
   1924           status = BTA_HL_STATUS_MCAP_REG_FAIL;
   1925           break;
   1926         }
   1927         if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle,
   1928                           &(p_acb->sup_feature.mdep[mdep_idx].mdep_id),
   1929                           &mca_cs) == MCA_SUCCESS) {
   1930           if (bta_hl_co_get_mdep_config(
   1931                   app_id, mdep_idx, mdep_counter,
   1932                   p_acb->sup_feature.mdep[mdep_idx].mdep_id,
   1933                   &p_acb->sup_feature.mdep[mdep_idx].mdep_cfg)) {
   1934             p_acb->sup_feature.mdep[mdep_idx].ori_app_id = app_id;
   1935             APPL_TRACE_DEBUG("mdep idx %d id %d ori_app_id %d num data type %d",
   1936                              mdep_idx,
   1937                              p_acb->sup_feature.mdep[mdep_idx].mdep_id,
   1938                              p_acb->sup_feature.mdep[mdep_idx].ori_app_id,
   1939                              p_acb->sup_feature.mdep[mdep_idx]
   1940                                  .mdep_cfg.num_of_mdep_data_types);
   1941             if (p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role ==
   1942                 BTA_HL_MDEP_ROLE_SOURCE) {
   1943               p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SOURCE;
   1944             } else if (p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role ==
   1945                        BTA_HL_MDEP_ROLE_SINK) {
   1946               p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SINK;
   1947             } else {
   1948               APPL_TRACE_ERROR(
   1949                   "bta_hl_app_registration: Invalid Role %d",
   1950                   p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role);
   1951               status = BTA_HL_STATUS_MDEP_CO_FAIL;
   1952               break;
   1953             }
   1954           } else {
   1955             APPL_TRACE_ERROR("bta_hl_app_registration: Cfg callout failed");
   1956             status = BTA_HL_STATUS_MDEP_CO_FAIL;
   1957             break;
   1958           }
   1959         } else {
   1960           APPL_TRACE_ERROR("bta_hl_app_registration: MCA_CreateDep failed");
   1961           status = BTA_HL_STATUS_MCAP_REG_FAIL;
   1962           break;
   1963         }
   1964       }
   1965       p_acb->sup_feature.num_of_mdeps += num_of_mdeps;
   1966       APPL_TRACE_DEBUG("num_of_mdeps %d", p_acb->sup_feature.num_of_mdeps);
   1967 
   1968       if ((status == BTA_HL_STATUS_OK) &&
   1969           (p_acb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SOURCE)) {
   1970         p_acb->sup_feature.advertize_source_sdp =
   1971             bta_hl_co_advrtise_source_sdp(app_id);
   1972       }
   1973 
   1974       if ((status == BTA_HL_STATUS_OK) &&
   1975           (!bta_hl_co_get_echo_config(app_id, &p_acb->sup_feature.echo_cfg))) {
   1976         status = BTA_HL_STATUS_ECHO_CO_FAIL;
   1977       }
   1978 
   1979       if ((status == BTA_HL_STATUS_OK) &&
   1980           (!bta_hl_co_load_mdl_config(app_id, BTA_HL_NUM_MDL_CFGS,
   1981                                       &p_acb->mdl_cfg[0]))) {
   1982         status = BTA_HL_STATUS_MDL_CFG_CO_FAIL;
   1983       }
   1984     } else {
   1985       status = BTA_HL_STATUS_MDEP_CO_FAIL;
   1986     }
   1987   } else {
   1988     for (i = 1; i < BTA_HL_NUM_MDEPS; i++) {
   1989       if (p_acb->sup_feature.mdep[i].ori_app_id == app_id) {
   1990         APPL_TRACE_DEBUG("Found index %", i);
   1991 
   1992         if (MCA_DeleteDep((tMCA_HANDLE)p_acb->app_handle,
   1993                           (p_acb->sup_feature.mdep[i].mdep_id)) !=
   1994             MCA_SUCCESS) {
   1995           APPL_TRACE_ERROR("Error deregistering");
   1996           status = BTA_HL_STATUS_MCAP_REG_FAIL;
   1997           return status;
   1998         }
   1999         memset(&p_acb->sup_feature.mdep[i], 0, sizeof(tBTA_HL_MDEP));
   2000       }
   2001     }
   2002   }
   2003 
   2004   if (status == BTA_HL_STATUS_OK) {
   2005     /* Register/Update MDEP(s) in SDP Record */
   2006     status = bta_hl_sdp_update(app_id);
   2007   }
   2008   /* else do cleanup */
   2009 
   2010   return status;
   2011 }
   2012 
   2013 /*******************************************************************************
   2014  *
   2015  * Function      bta_hl_app_registration
   2016  *
   2017  * Description  This function registers an HDP application MCAP and DP
   2018  *
   2019  * Returns      tBTA_HL_STATUS -registration status
   2020  *
   2021  ******************************************************************************/
   2022 tBTA_HL_STATUS bta_hl_app_registration(uint8_t app_idx) {
   2023   tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
   2024   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   2025   tMCA_REG reg;
   2026   tMCA_CS mca_cs;
   2027   uint8_t i, num_of_mdeps;
   2028   uint8_t mdep_counter = 0;
   2029 
   2030 #if (BTA_HL_DEBUG == TRUE)
   2031   APPL_TRACE_DEBUG("bta_hl_app_registration app_idx=%d", app_idx);
   2032 #endif
   2033 
   2034   reg.ctrl_psm = p_acb->ctrl_psm;
   2035   reg.data_psm = p_acb->data_psm;
   2036   reg.sec_mask = p_acb->sec_mask;
   2037   reg.rsp_tout = BTA_HL_MCAP_RSP_TOUT;
   2038 
   2039   p_acb->app_handle =
   2040       (tBTA_HL_APP_HANDLE)MCA_Register(&reg, bta_hl_mcap_ctrl_cback);
   2041   if (p_acb->app_handle != 0) {
   2042     mca_cs.type = MCA_TDEP_ECHO;
   2043     mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP;
   2044     mca_cs.p_data_cback = bta_hl_mcap_data_cback;
   2045 
   2046     if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle,
   2047                       &(p_acb->sup_feature.mdep[0].mdep_id),
   2048                       &mca_cs) == MCA_SUCCESS) {
   2049       if (p_acb->sup_feature.mdep[0].mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) {
   2050         status = BTA_HL_STATUS_MCAP_REG_FAIL;
   2051         APPL_TRACE_ERROR("BAD MDEP ID for echo test mdep_id=%d",
   2052                          p_acb->sup_feature.mdep[0].mdep_id);
   2053       }
   2054     } else {
   2055       status = BTA_HL_STATUS_MCAP_REG_FAIL;
   2056       APPL_TRACE_ERROR("MCA_CreateDep for echo test(mdep_id=0) failed");
   2057     }
   2058 
   2059     if ((status == BTA_HL_STATUS_OK) &&
   2060         bta_hl_co_get_num_of_mdep(p_acb->app_id, &num_of_mdeps)) {
   2061       p_acb->sup_feature.num_of_mdeps = num_of_mdeps + 1;
   2062 
   2063       for (i = 1; i < p_acb->sup_feature.num_of_mdeps; i++) {
   2064         mca_cs.type = MCA_TDEP_DATA;
   2065         mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP;
   2066         mca_cs.p_data_cback = bta_hl_mcap_data_cback;
   2067 
   2068         if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle,
   2069                           &(p_acb->sup_feature.mdep[i].mdep_id),
   2070                           &mca_cs) == MCA_SUCCESS) {
   2071           if (bta_hl_co_get_mdep_config(p_acb->app_id, i, mdep_counter,
   2072                                         p_acb->sup_feature.mdep[i].mdep_id,
   2073                                         &p_acb->sup_feature.mdep[i].mdep_cfg)) {
   2074             if (p_acb->sup_feature.mdep[i].mdep_cfg.mdep_role ==
   2075                 BTA_HL_MDEP_ROLE_SOURCE) {
   2076               p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SOURCE;
   2077             } else if (p_acb->sup_feature.mdep[i].mdep_cfg.mdep_role ==
   2078                        BTA_HL_MDEP_ROLE_SINK) {
   2079               p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SINK;
   2080             } else {
   2081               status = BTA_HL_STATUS_MDEP_CO_FAIL;
   2082               break;
   2083             }
   2084             p_acb->sup_feature.mdep[i].ori_app_id = p_acb->app_id;
   2085             APPL_TRACE_DEBUG("index %d ori_app_id %d", i,
   2086                              p_acb->sup_feature.mdep[i].ori_app_id);
   2087           } else {
   2088             status = BTA_HL_STATUS_MDEP_CO_FAIL;
   2089             break;
   2090           }
   2091         } else {
   2092           status = BTA_HL_STATUS_MCAP_REG_FAIL;
   2093           break;
   2094         }
   2095       }
   2096 
   2097       if ((status == BTA_HL_STATUS_OK) &&
   2098           (p_acb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SOURCE)) {
   2099         /* this is a source only applciation */
   2100         p_acb->sup_feature.advertize_source_sdp =
   2101             bta_hl_co_advrtise_source_sdp(p_acb->app_id);
   2102       }
   2103 
   2104       if ((status == BTA_HL_STATUS_OK) &&
   2105           (!bta_hl_co_get_echo_config(p_acb->app_id,
   2106                                       &p_acb->sup_feature.echo_cfg))) {
   2107         status = BTA_HL_STATUS_ECHO_CO_FAIL;
   2108       }
   2109 
   2110       if ((status == BTA_HL_STATUS_OK) &&
   2111           (!bta_hl_co_load_mdl_config(p_acb->app_id, BTA_HL_NUM_MDL_CFGS,
   2112                                       &p_acb->mdl_cfg[0]))) {
   2113         status = BTA_HL_STATUS_MDL_CFG_CO_FAIL;
   2114       }
   2115     } else {
   2116       status = BTA_HL_STATUS_MDEP_CO_FAIL;
   2117     }
   2118   } else {
   2119     status = BTA_HL_STATUS_MCAP_REG_FAIL;
   2120   }
   2121 
   2122   if (status == BTA_HL_STATUS_OK) {
   2123     status = bta_hl_sdp_register(app_idx);
   2124   }
   2125 
   2126   return status;
   2127 }
   2128 
   2129 /*******************************************************************************
   2130  *
   2131  * Function         bta_hl_discard_data
   2132  *
   2133  * Description  This function discard an HDP event
   2134  *
   2135  * Returns     void
   2136  *
   2137  ******************************************************************************/
   2138 void bta_hl_discard_data(uint16_t event, tBTA_HL_DATA* p_data) {
   2139 #if (BTA_HL_DEBUG == TRUE)
   2140   APPL_TRACE_ERROR("BTA HL Discard event=%s", bta_hl_evt_code(event));
   2141 
   2142 #endif
   2143 
   2144   switch (event) {
   2145     case BTA_HL_API_SEND_DATA_EVT:
   2146       break;
   2147 
   2148     case BTA_HL_MCA_RCV_DATA_EVT:
   2149       osi_free_and_reset((void**)&p_data->mca_rcv_data_evt.p_pkt);
   2150       break;
   2151 
   2152     default:
   2153       /*Nothing to free*/
   2154       break;
   2155   }
   2156 }
   2157 
   2158 /*******************************************************************************
   2159  *
   2160  * Function         bta_hl_save_mdl_cfg
   2161  *
   2162  * Description    This function saves the MDL configuration
   2163  *
   2164  * Returns     void
   2165  *
   2166  ******************************************************************************/
   2167 void bta_hl_save_mdl_cfg(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx) {
   2168   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   2169   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
   2170   tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
   2171   uint8_t mdl_cfg_idx;
   2172   tBTA_HL_MDL_ID mdl_id;
   2173   bool found = true;
   2174   tBTA_HL_MDL_CFG mdl_cfg;
   2175   tBTA_HL_MDEP* p_mdep_cfg;
   2176   tBTA_HL_L2CAP_CFG_INFO l2cap_cfg;
   2177   uint8_t time_val = 0;
   2178   mdl_id = p_dcb->mdl_id;
   2179   if (!bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, mdl_id, &mdl_cfg_idx)) {
   2180     if (!bta_hl_find_avail_mdl_cfg_idx(app_idx, mcl_idx, &mdl_cfg_idx)) {
   2181       APPL_TRACE_ERROR("No space to save the MDL config");
   2182       found = false; /*no space available*/
   2183     }
   2184   }
   2185 
   2186   if (found) {
   2187     bta_hl_get_l2cap_cfg(p_dcb->mdl_handle, &l2cap_cfg);
   2188     if (!bta_hl_get_cur_time(app_idx, &time_val)) {
   2189       bta_hl_compact_mdl_cfg_time(app_idx, p_dcb->local_mdep_id);
   2190       bta_hl_get_cur_time(app_idx, &time_val);
   2191     }
   2192     mdl_cfg.active = true;
   2193     mdl_cfg.time = time_val;
   2194     mdl_cfg.mdl_id = p_dcb->mdl_id;
   2195     mdl_cfg.dch_mode = p_dcb->dch_mode;
   2196     mdl_cfg.mtu = l2cap_cfg.mtu;
   2197     mdl_cfg.fcs = l2cap_cfg.fcs;
   2198 
   2199     bdcpy(mdl_cfg.peer_bd_addr, p_mcb->bd_addr);
   2200     mdl_cfg.local_mdep_id = p_dcb->local_mdep_id;
   2201     p_mdep_cfg = &p_acb->sup_feature.mdep[p_dcb->local_mdep_cfg_idx];
   2202     mdl_cfg.local_mdep_role = p_mdep_cfg->mdep_cfg.mdep_role;
   2203     memcpy(&p_acb->mdl_cfg[mdl_cfg_idx], &mdl_cfg, sizeof(tBTA_HL_MDL_CFG));
   2204     bta_hl_co_save_mdl(mdl_cfg.local_mdep_id, mdl_cfg_idx, &mdl_cfg);
   2205   }
   2206 
   2207 #if (BTA_HL_DEBUG == TRUE)
   2208   if (found) {
   2209     if (p_dcb->mtu != l2cap_cfg.mtu) {
   2210       APPL_TRACE_WARNING(
   2211           "MCAP and L2CAP peer mtu size out of sync from MCAP mtu=%d from "
   2212           "l2cap mtu=%d",
   2213           p_dcb->mtu, l2cap_cfg.mtu);
   2214     }
   2215     APPL_TRACE_DEBUG("bta_hl_save_mdl_cfg saved=%d", found);
   2216     APPL_TRACE_DEBUG("Saved. L2cap cfg mdl_id=%d mtu=%d fcs=%d dch_mode=%d",
   2217                      mdl_cfg.mdl_id, mdl_cfg.mtu, mdl_cfg.fcs,
   2218                      mdl_cfg.dch_mode);
   2219   }
   2220 #endif
   2221 }
   2222 
   2223 /*******************************************************************************
   2224  *
   2225  * Function      bta_hl_set_dch_chan_cfg
   2226  *
   2227  * Description    This function setups the L2CAP DCH channel configuration
   2228  *
   2229  * Returns     void
   2230  ******************************************************************************/
   2231 void bta_hl_set_dch_chan_cfg(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
   2232                              tBTA_HL_DATA* p_data) {
   2233   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   2234   tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
   2235   uint8_t l2cap_mode = L2CAP_FCR_ERTM_MODE;
   2236   tBTA_HL_SUP_FEATURE* p_sup_feature = &p_acb->sup_feature;
   2237   uint8_t local_mdep_cfg_idx = p_dcb->local_mdep_cfg_idx;
   2238 
   2239   switch (p_dcb->dch_oper) {
   2240     case BTA_HL_DCH_OP_LOCAL_RECONNECT:
   2241     case BTA_HL_DCH_OP_REMOTE_RECONNECT:
   2242       if (p_dcb->dch_mode == BTA_HL_DCH_MODE_STREAMING)
   2243         l2cap_mode = L2CAP_FCR_STREAM_MODE;
   2244       break;
   2245     case BTA_HL_DCH_OP_LOCAL_OPEN:
   2246       if (p_data->mca_evt.mca_data.create_cfm.cfg == BTA_HL_DCH_CFG_STREAMING)
   2247         l2cap_mode = L2CAP_FCR_STREAM_MODE;
   2248       break;
   2249     case BTA_HL_DCH_OP_REMOTE_OPEN:
   2250       if (p_dcb->local_cfg == BTA_HL_DCH_CFG_STREAMING)
   2251         l2cap_mode = L2CAP_FCR_STREAM_MODE;
   2252       break;
   2253     default:
   2254       APPL_TRACE_ERROR("Invalid dch oper=%d for set dch chan cfg",
   2255                        p_dcb->dch_oper);
   2256       break;
   2257   }
   2258   p_dcb->chnl_cfg.fcr_opt.mode = l2cap_mode;
   2259   p_dcb->chnl_cfg.fcr_opt.mps = bta_hl_set_mps(p_dcb->max_rx_apdu_size);
   2260   p_dcb->chnl_cfg.fcr_opt.tx_win_sz = bta_hl_set_tx_win_size(
   2261       p_dcb->max_rx_apdu_size, p_dcb->chnl_cfg.fcr_opt.mps);
   2262   p_dcb->chnl_cfg.fcr_opt.max_transmit = BTA_HL_L2C_MAX_TRANSMIT;
   2263   p_dcb->chnl_cfg.fcr_opt.rtrans_tout = BTA_HL_L2C_RTRANS_TOUT;
   2264   p_dcb->chnl_cfg.fcr_opt.mon_tout = BTA_HL_L2C_MON_TOUT;
   2265 
   2266   p_dcb->chnl_cfg.user_rx_buf_size =
   2267       bta_hl_set_user_rx_buf_size(p_dcb->max_rx_apdu_size);
   2268   p_dcb->chnl_cfg.user_tx_buf_size =
   2269       bta_hl_set_user_tx_buf_size(p_dcb->max_tx_apdu_size);
   2270   p_dcb->chnl_cfg.fcr_rx_buf_size = L2CAP_INVALID_ERM_BUF_SIZE;
   2271   p_dcb->chnl_cfg.fcr_tx_buf_size = L2CAP_INVALID_ERM_BUF_SIZE;
   2272   p_dcb->chnl_cfg.data_mtu = p_dcb->max_rx_apdu_size;
   2273 
   2274   p_dcb->chnl_cfg.fcs = BTA_HL_MCA_NO_FCS;
   2275   if (local_mdep_cfg_idx != BTA_HL_ECHO_TEST_MDEP_CFG_IDX) {
   2276     if (p_sup_feature->mdep[local_mdep_cfg_idx].mdep_cfg.mdep_role ==
   2277         BTA_HL_MDEP_ROLE_SOURCE) {
   2278       p_dcb->chnl_cfg.fcs = BTA_HL_DEFAULT_SOURCE_FCS;
   2279     }
   2280   } else {
   2281     p_dcb->chnl_cfg.fcs = BTA_HL_MCA_USE_FCS;
   2282   }
   2283 
   2284 #if (BTA_HL_DEBUG == TRUE)
   2285   APPL_TRACE_DEBUG("L2CAP Params l2cap_mode[3-ERTM 4-STREAM]=%d", l2cap_mode);
   2286   APPL_TRACE_DEBUG("Use FCS =%s mtu=%d",
   2287                    ((p_dcb->chnl_cfg.fcs & 1) ? "YES" : "NO"),
   2288                    p_dcb->chnl_cfg.data_mtu);
   2289   APPL_TRACE_DEBUG(
   2290       "tx_win_sz=%d, max_transmit=%d, rtrans_tout=%d, mon_tout=%d, mps=%d",
   2291       p_dcb->chnl_cfg.fcr_opt.tx_win_sz, p_dcb->chnl_cfg.fcr_opt.max_transmit,
   2292       p_dcb->chnl_cfg.fcr_opt.rtrans_tout, p_dcb->chnl_cfg.fcr_opt.mon_tout,
   2293       p_dcb->chnl_cfg.fcr_opt.mps);
   2294 
   2295   APPL_TRACE_DEBUG(
   2296       "USER rx_buf_size=%d, tx_buf_size=%d, FCR rx_buf_size=%d, tx_buf_size=%d",
   2297       p_dcb->chnl_cfg.user_rx_buf_size, p_dcb->chnl_cfg.user_tx_buf_size,
   2298       p_dcb->chnl_cfg.fcr_rx_buf_size, p_dcb->chnl_cfg.fcr_tx_buf_size);
   2299 
   2300 #endif
   2301 }
   2302 
   2303 /*******************************************************************************
   2304  *
   2305  * Function      bta_hl_get_l2cap_cfg
   2306  *
   2307  * Description    This function get the current L2CAP channel configuration
   2308  *
   2309  * Returns     bool - true - operation is successful
   2310  ******************************************************************************/
   2311 bool bta_hl_get_l2cap_cfg(tBTA_HL_MDL_HANDLE mdl_hnd,
   2312                           tBTA_HL_L2CAP_CFG_INFO* p_cfg) {
   2313   bool success = false;
   2314   uint16_t lcid;
   2315   tL2CAP_CFG_INFO* p_our_cfg;
   2316   tL2CAP_CH_CFG_BITS our_cfg_bits;
   2317   tL2CAP_CFG_INFO* p_peer_cfg;
   2318   tL2CAP_CH_CFG_BITS peer_cfg_bits;
   2319 
   2320   lcid = MCA_GetL2CapChannel((tMCA_DL)mdl_hnd);
   2321   if (lcid && L2CA_GetCurrentConfig(lcid, &p_our_cfg, &our_cfg_bits,
   2322                                     &p_peer_cfg, &peer_cfg_bits)) {
   2323     p_cfg->fcs = BTA_HL_MCA_NO_FCS;
   2324     if (our_cfg_bits & L2CAP_CH_CFG_MASK_FCS) {
   2325       p_cfg->fcs |= p_our_cfg->fcs;
   2326     } else {
   2327       p_cfg->fcs = BTA_HL_MCA_USE_FCS;
   2328     }
   2329 
   2330     if (p_cfg->fcs != BTA_HL_MCA_USE_FCS) {
   2331       if (peer_cfg_bits & L2CAP_CH_CFG_MASK_FCS) {
   2332         p_cfg->fcs |= p_peer_cfg->fcs;
   2333       } else {
   2334         p_cfg->fcs = BTA_HL_MCA_USE_FCS;
   2335       }
   2336     }
   2337 
   2338     p_cfg->mtu = 0;
   2339     if (peer_cfg_bits & L2CAP_CH_CFG_MASK_MTU) {
   2340       p_cfg->mtu = p_peer_cfg->mtu;
   2341     } else {
   2342       p_cfg->mtu = L2CAP_DEFAULT_MTU;
   2343     }
   2344     success = true;
   2345   } else {
   2346     p_cfg->mtu = L2CAP_DEFAULT_MTU;
   2347     p_cfg->fcs = BTA_HL_L2C_NO_FCS;
   2348   }
   2349 
   2350 #if (BTA_HL_DEBUG == TRUE)
   2351   if (!success) {
   2352     APPL_TRACE_DEBUG("bta_hl_get_l2cap_cfg success=%d mdl=%d lcid=%d", success,
   2353                      mdl_hnd, lcid);
   2354     APPL_TRACE_DEBUG("l2cap mtu=%d fcs=%d", p_cfg->mtu, p_cfg->fcs);
   2355   }
   2356 #endif
   2357 
   2358   return success;
   2359 }
   2360 
   2361 /*******************************************************************************
   2362  *
   2363  * Function      bta_hl_validate_chan_cfg
   2364  *
   2365  * Description    This function validates the L2CAP channel configuration
   2366  *
   2367  * Returns     bool - true - validation is successful
   2368  ******************************************************************************/
   2369 bool bta_hl_validate_chan_cfg(uint8_t app_idx, uint8_t mcl_idx,
   2370                               uint8_t mdl_idx) {
   2371   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   2372   tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
   2373   bool success = false;
   2374   uint8_t mdl_cfg_idx = 0;
   2375   tBTA_HL_L2CAP_CFG_INFO l2cap_cfg;
   2376   bool get_l2cap_result, get_mdl_result;
   2377 
   2378   get_l2cap_result = bta_hl_get_l2cap_cfg(p_dcb->mdl_handle, &l2cap_cfg);
   2379   get_mdl_result =
   2380       bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, p_dcb->mdl_id, &mdl_cfg_idx);
   2381 
   2382   if (get_l2cap_result && get_mdl_result) {
   2383     if ((p_acb->mdl_cfg[mdl_cfg_idx].mtu <= l2cap_cfg.mtu) &&
   2384         (p_acb->mdl_cfg[mdl_cfg_idx].fcs == l2cap_cfg.fcs) &&
   2385         (p_acb->mdl_cfg[mdl_cfg_idx].dch_mode == p_dcb->dch_mode)) {
   2386       success = true;
   2387     }
   2388   }
   2389 
   2390 #if (BTA_HL_DEBUG == TRUE)
   2391 
   2392   if (p_dcb->mtu != l2cap_cfg.mtu) {
   2393     APPL_TRACE_WARNING(
   2394         "MCAP and L2CAP peer mtu size out of sync from MCAP mtu=%d from l2cap "
   2395         "mtu=%d",
   2396         p_dcb->mtu, l2cap_cfg.mtu);
   2397   }
   2398 
   2399   if (!success) {
   2400     APPL_TRACE_DEBUG(
   2401         "bta_hl_validate_chan_cfg success=%d app_idx=%d mcl_idx=%d mdl_idx=%d",
   2402         success, app_idx, mcl_idx, mdl_idx);
   2403     APPL_TRACE_DEBUG("Cur. L2cap cfg mtu=%d fcs=%d dch_mode=%d", l2cap_cfg.mtu,
   2404                      l2cap_cfg.fcs, p_dcb->dch_mode);
   2405     APPL_TRACE_DEBUG("From saved: L2cap cfg mtu=%d fcs=%d dch_mode=%d",
   2406                      p_acb->mdl_cfg[mdl_cfg_idx].mtu,
   2407                      p_acb->mdl_cfg[mdl_cfg_idx].fcs,
   2408                      p_acb->mdl_cfg[mdl_cfg_idx].dch_mode);
   2409   }
   2410 #endif
   2411 
   2412   return success;
   2413 }
   2414 
   2415 /*******************************************************************************
   2416  *
   2417  * Function      bta_hl_is_cong_on
   2418  *
   2419  * Description    This function checks whether the congestion condition is on.
   2420  *
   2421  * Returns      bool - true DCH is congested
   2422  *                        false not congested
   2423  *
   2424  ******************************************************************************/
   2425 bool bta_hl_is_cong_on(uint8_t app_id, BD_ADDR bd_addr, tBTA_HL_MDL_ID mdl_id)
   2426 
   2427 {
   2428   tBTA_HL_MDL_CB* p_dcb;
   2429   uint8_t app_idx = 0, mcl_idx, mdl_idx;
   2430   bool cong_status = true;
   2431 
   2432   if (bta_hl_find_app_idx(app_id, &app_idx)) {
   2433     if (bta_hl_find_mcl_idx(app_idx, bd_addr, &mcl_idx)) {
   2434       if (bta_hl_find_mdl_idx(app_idx, mcl_idx, mdl_id, &mdl_idx)) {
   2435         p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
   2436         cong_status = p_dcb->cong;
   2437       }
   2438     }
   2439   }
   2440 
   2441   return cong_status;
   2442 }
   2443 
   2444 /*******************************************************************************
   2445  *
   2446  * Function      bta_hl_check_cch_close
   2447  *
   2448  * Description   This function checks whether there is a pending CCH close
   2449  *               request or not
   2450  *
   2451  * Returns      void
   2452  ******************************************************************************/
   2453 void bta_hl_check_cch_close(uint8_t app_idx, uint8_t mcl_idx,
   2454                             tBTA_HL_DATA* p_data, bool check_dch_setup) {
   2455   tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
   2456   tBTA_HL_MDL_CB* p_dcb;
   2457   uint8_t mdl_idx;
   2458 
   2459 #if (BTA_HL_DEBUG == TRUE)
   2460   APPL_TRACE_DEBUG("bta_hl_check_cch_close cch_close_dch_oper=%d",
   2461                    p_mcb->cch_close_dch_oper);
   2462 #endif
   2463 
   2464   if (p_mcb->cch_oper == BTA_HL_CCH_OP_LOCAL_CLOSE) {
   2465     if (check_dch_setup &&
   2466         bta_hl_find_dch_setup_mdl_idx(app_idx, mcl_idx, &mdl_idx)) {
   2467       p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
   2468       if (!p_mcb->rsp_tout) {
   2469         p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_ABORT;
   2470 
   2471         if (!p_dcb->abort_oper) {
   2472           p_dcb->abort_oper |= BTA_HL_ABORT_CCH_CLOSE_MASK;
   2473           bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_ABORT_EVT,
   2474                                 p_data);
   2475         }
   2476       } else {
   2477         p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_CLOSE;
   2478         bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
   2479                               BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
   2480       }
   2481     } else if (bta_hl_find_an_active_mdl_idx(app_idx, mcl_idx, &mdl_idx)) {
   2482       p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_CLOSE;
   2483       bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_EVT,
   2484                             p_data);
   2485     } else {
   2486       p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_NONE;
   2487       bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_EVT, p_data);
   2488     }
   2489   }
   2490 }
   2491 
   2492 /*******************************************************************************
   2493  *
   2494  * Function         bta_hl_clean_app
   2495  *
   2496  * Description      Cleans up the HDP application resources and control block
   2497  *
   2498  * Returns          void
   2499  *
   2500  ******************************************************************************/
   2501 void bta_hl_clean_app(uint8_t app_idx) {
   2502   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   2503   int i, num_act_apps = 0;
   2504 
   2505 #if (BTA_HL_DEBUG == TRUE)
   2506   APPL_TRACE_DEBUG("bta_hl_clean_app");
   2507 #endif
   2508   MCA_Deregister((tMCA_HANDLE)p_acb->app_handle);
   2509 
   2510   if (p_acb->sdp_handle) SDP_DeleteRecord(p_acb->sdp_handle);
   2511 
   2512   memset((void*)p_acb, 0, sizeof(tBTA_HL_APP_CB));
   2513 
   2514   /* check any application is still active */
   2515   for (i = 0; i < BTA_HL_NUM_APPS; i++) {
   2516     p_acb = BTA_HL_GET_APP_CB_PTR(i);
   2517     if (p_acb->in_use) num_act_apps++;
   2518   }
   2519 
   2520   if (!num_act_apps) {
   2521     bta_sys_remove_uuid(UUID_SERVCLASS_HDP_PROFILE);
   2522   }
   2523 }
   2524 
   2525 /*******************************************************************************
   2526  *
   2527  * Function      bta_hl_check_deregistration
   2528  *
   2529  * Description   This function checks whether there is a pending deregistration
   2530  *               request or not
   2531  *
   2532  * Returns      void
   2533  ******************************************************************************/
   2534 void bta_hl_check_deregistration(uint8_t app_idx, tBTA_HL_DATA* p_data) {
   2535   tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   2536   tBTA_HL_MCL_CB* p_mcb;
   2537   uint8_t mcl_idx;
   2538   tBTA_HL evt_data;
   2539 
   2540 #if (BTA_HL_DEBUG == TRUE)
   2541   APPL_TRACE_DEBUG("bta_hl_check_deregistration");
   2542 #endif
   2543 
   2544   if (p_acb->deregistering) {
   2545     if (bta_hl_find_an_in_use_mcl_idx(app_idx, &mcl_idx)) {
   2546       p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
   2547       if (p_mcb->cch_oper != BTA_HL_CCH_OP_LOCAL_CLOSE) {
   2548         if (p_mcb->cch_state == BTA_HL_CCH_OPENING_ST)
   2549           p_mcb->force_close_local_cch_opening = true;
   2550         p_mcb->cch_oper = BTA_HL_CCH_OP_LOCAL_CLOSE;
   2551         APPL_TRACE_DEBUG("p_mcb->force_close_local_cch_opening=%d",
   2552                          p_mcb->force_close_local_cch_opening);
   2553         bta_hl_check_cch_close(app_idx, mcl_idx, p_data, true);
   2554       }
   2555     } else {
   2556       /* all cchs are closed */
   2557       evt_data.dereg_cfm.app_handle = p_acb->app_handle;
   2558       evt_data.dereg_cfm.app_id = p_data->api_dereg.app_id;
   2559       evt_data.dereg_cfm.status = BTA_HL_STATUS_OK;
   2560       p_acb->p_cback(BTA_HL_DEREGISTER_CFM_EVT, (tBTA_HL*)&evt_data);
   2561       bta_hl_clean_app(app_idx);
   2562       bta_hl_check_disable(p_data);
   2563     }
   2564   }
   2565 }
   2566 
   2567 /*******************************************************************************
   2568  *
   2569  * Function      bta_hl_check_disable
   2570  *
   2571  * Description   This function checks whether there is a pending disable
   2572  *               request or not
   2573  *
   2574  * Returns      void
   2575  *
   2576  ******************************************************************************/
   2577 void bta_hl_check_disable(tBTA_HL_DATA* p_data) {
   2578   tBTA_HL_CB* p_cb = &bta_hl_cb;
   2579   tBTA_HL_APP_CB* p_acb;
   2580   uint8_t app_idx;
   2581   tBTA_HL_CTRL evt_data;
   2582 
   2583 #if (BTA_HL_DEBUG == TRUE)
   2584   APPL_TRACE_DEBUG("bta_hl_check_disable");
   2585 #endif
   2586 
   2587   if (bta_hl_cb.disabling) {
   2588     if (bta_hl_find_an_in_use_app_idx(&app_idx)) {
   2589       p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
   2590       if (!p_acb->deregistering) {
   2591         p_acb->deregistering = true;
   2592         bta_hl_check_deregistration(app_idx, p_data);
   2593       }
   2594     } else {
   2595       /* all apps are deregistered */
   2596       bta_sys_deregister(BTA_ID_HL);
   2597       evt_data.disable_cfm.status = BTA_HL_STATUS_OK;
   2598       if (p_cb->p_ctrl_cback)
   2599         p_cb->p_ctrl_cback(BTA_HL_CTRL_DISABLE_CFM_EVT,
   2600                            (tBTA_HL_CTRL*)&evt_data);
   2601       memset((void*)p_cb, 0, sizeof(tBTA_HL_CB));
   2602     }
   2603   }
   2604 }
   2605 
   2606 /*******************************************************************************
   2607  *
   2608  * Function      bta_hl_build_abort_cfm
   2609  *
   2610  * Description   This function builds the abort confirmation event data
   2611  *
   2612  * Returns      None
   2613  *
   2614  ******************************************************************************/
   2615 void bta_hl_build_abort_cfm(tBTA_HL* p_evt_data, tBTA_HL_APP_HANDLE app_handle,
   2616                             tBTA_HL_MCL_HANDLE mcl_handle,
   2617                             tBTA_HL_STATUS status) {
   2618   p_evt_data->dch_abort_cfm.status = status;
   2619   p_evt_data->dch_abort_cfm.mcl_handle = mcl_handle;
   2620   p_evt_data->dch_abort_cfm.app_handle = app_handle;
   2621 }
   2622 
   2623 /*******************************************************************************
   2624  *
   2625  * Function      bta_hl_build_abort_ind
   2626  *
   2627  * Description   This function builds the abort indication event data
   2628  *
   2629  * Returns      None
   2630  *
   2631  ******************************************************************************/
   2632 void bta_hl_build_abort_ind(tBTA_HL* p_evt_data, tBTA_HL_APP_HANDLE app_handle,
   2633                             tBTA_HL_MCL_HANDLE mcl_handle) {
   2634   p_evt_data->dch_abort_ind.mcl_handle = mcl_handle;
   2635   p_evt_data->dch_abort_ind.app_handle = app_handle;
   2636 }
   2637 /*******************************************************************************
   2638  *
   2639  * Function      bta_hl_build_close_cfm
   2640  *
   2641  * Description   This function builds the close confirmation event data
   2642  *
   2643  * Returns      None
   2644  *
   2645  ******************************************************************************/
   2646 void bta_hl_build_dch_close_cfm(tBTA_HL* p_evt_data,
   2647                                 tBTA_HL_APP_HANDLE app_handle,
   2648                                 tBTA_HL_MCL_HANDLE mcl_handle,
   2649                                 tBTA_HL_MDL_HANDLE mdl_handle,
   2650                                 tBTA_HL_STATUS status) {
   2651   p_evt_data->dch_close_cfm.status = status;
   2652   p_evt_data->dch_close_cfm.mdl_handle = mdl_handle;
   2653   p_evt_data->dch_close_cfm.mcl_handle = mcl_handle;
   2654   p_evt_data->dch_close_cfm.app_handle = app_handle;
   2655 }
   2656 
   2657 /*******************************************************************************
   2658  *
   2659  * Function      bta_hl_build_dch_close_ind
   2660  *
   2661  * Description   This function builds the close indication event data
   2662  *
   2663  * Returns      None
   2664  *
   2665  ******************************************************************************/
   2666 void bta_hl_build_dch_close_ind(tBTA_HL* p_evt_data,
   2667                                 tBTA_HL_APP_HANDLE app_handle,
   2668                                 tBTA_HL_MCL_HANDLE mcl_handle,
   2669                                 tBTA_HL_MDL_HANDLE mdl_handle,
   2670                                 bool intentional) {
   2671   p_evt_data->dch_close_ind.mdl_handle = mdl_handle;
   2672   p_evt_data->dch_close_ind.mcl_handle = mcl_handle;
   2673   p_evt_data->dch_close_ind.app_handle = app_handle;
   2674   p_evt_data->dch_close_ind.intentional = intentional;
   2675 }
   2676 
   2677 /*******************************************************************************
   2678  *
   2679  * Function      bta_hl_build_send_data_cfm
   2680  *
   2681  * Description   This function builds the send data confirmation event data
   2682  *
   2683  * Returns      None
   2684  *
   2685  ******************************************************************************/
   2686 void bta_hl_build_send_data_cfm(tBTA_HL* p_evt_data,
   2687                                 tBTA_HL_APP_HANDLE app_handle,
   2688                                 tBTA_HL_MCL_HANDLE mcl_handle,
   2689                                 tBTA_HL_MDL_HANDLE mdl_handle,
   2690                                 tBTA_HL_STATUS status) {
   2691   p_evt_data->dch_send_data_cfm.mdl_handle = mdl_handle;
   2692   p_evt_data->dch_send_data_cfm.mcl_handle = mcl_handle;
   2693   p_evt_data->dch_send_data_cfm.app_handle = app_handle;
   2694   p_evt_data->dch_send_data_cfm.status = status;
   2695 }
   2696 
   2697 /*******************************************************************************
   2698  *
   2699  * Function      bta_hl_build_rcv_data_ind
   2700  *
   2701  * Description   This function builds the received data indication event data
   2702  *
   2703  * Returns      None
   2704  *
   2705  ******************************************************************************/
   2706 void bta_hl_build_rcv_data_ind(tBTA_HL* p_evt_data,
   2707                                tBTA_HL_APP_HANDLE app_handle,
   2708                                tBTA_HL_MCL_HANDLE mcl_handle,
   2709                                tBTA_HL_MDL_HANDLE mdl_handle) {
   2710   p_evt_data->dch_rcv_data_ind.mdl_handle = mdl_handle;
   2711   p_evt_data->dch_rcv_data_ind.mcl_handle = mcl_handle;
   2712   p_evt_data->dch_rcv_data_ind.app_handle = app_handle;
   2713 }
   2714 
   2715 /*******************************************************************************
   2716  *
   2717  * Function      bta_hl_build_cch_open_cfm
   2718  *
   2719  * Description   This function builds the CCH open confirmation event data
   2720  *
   2721  * Returns      None
   2722  *
   2723  ******************************************************************************/
   2724 void bta_hl_build_cch_open_cfm(tBTA_HL* p_evt_data, uint8_t app_id,
   2725                                tBTA_HL_APP_HANDLE app_handle,
   2726                                tBTA_HL_MCL_HANDLE mcl_handle, BD_ADDR bd_addr,
   2727                                tBTA_HL_STATUS status) {
   2728   p_evt_data->cch_open_cfm.app_id = app_id;
   2729   p_evt_data->cch_open_cfm.app_handle = app_handle;
   2730   p_evt_data->cch_open_cfm.mcl_handle = mcl_handle;
   2731   bdcpy(p_evt_data->cch_open_cfm.bd_addr, bd_addr);
   2732   p_evt_data->cch_open_cfm.status = status;
   2733   APPL_TRACE_DEBUG("bta_hl_build_cch_open_cfm: status=%d", status);
   2734 }
   2735 
   2736 /*******************************************************************************
   2737  *
   2738  * Function      bta_hl_build_cch_open_ind
   2739  *
   2740  * Description   This function builds the CCH open indication event data
   2741  *
   2742  * Returns      None
   2743  *
   2744  ******************************************************************************/
   2745 void bta_hl_build_cch_open_ind(tBTA_HL* p_evt_data,
   2746                                tBTA_HL_APP_HANDLE app_handle,
   2747                                tBTA_HL_MCL_HANDLE mcl_handle, BD_ADDR 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   bdcpy(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, BD_ADDR bd_addr,
   2830                                 tBTA_HL_SDP* p_sdp, tBTA_HL_STATUS status)
   2831 
   2832 {
   2833   APPL_TRACE_DEBUG("bta_hl_build_sdp_query_cfm: app_id = %d, app_handle=%d",
   2834                    app_id, app_handle);
   2835   p_evt_data->sdp_query_cfm.app_id = app_id;
   2836   p_evt_data->sdp_query_cfm.app_handle = app_handle;
   2837   bdcpy(p_evt_data->sdp_query_cfm.bd_addr, bd_addr);
   2838   p_evt_data->sdp_query_cfm.p_sdp = p_sdp;
   2839   p_evt_data->sdp_query_cfm.status = status;
   2840 }
   2841 
   2842 /*******************************************************************************
   2843  *
   2844  * Function      bta_hl_build_delete_mdl_cfm
   2845  *
   2846  * Description   This function builds the delete MDL confirmation event data
   2847  *
   2848  * Returns      None
   2849  *
   2850  ******************************************************************************/
   2851 void bta_hl_build_delete_mdl_cfm(tBTA_HL* p_evt_data,
   2852                                  tBTA_HL_APP_HANDLE app_handle,
   2853                                  tBTA_HL_MCL_HANDLE mcl_handle,
   2854                                  tBTA_HL_MDL_ID mdl_id, tBTA_HL_STATUS status)
   2855 
   2856 {
   2857   p_evt_data->delete_mdl_cfm.mcl_handle = mcl_handle;
   2858   p_evt_data->delete_mdl_cfm.app_handle = app_handle;
   2859   p_evt_data->delete_mdl_cfm.mdl_id = mdl_id;
   2860   p_evt_data->delete_mdl_cfm.status = status;
   2861 }
   2862 
   2863 /*******************************************************************************
   2864  *
   2865  * Function      bta_hl_build_echo_test_cfm
   2866  *
   2867  * Description   This function builds the echo test confirmation event data
   2868  *
   2869  * Returns      None
   2870  *
   2871  ******************************************************************************/
   2872 void bta_hl_build_echo_test_cfm(tBTA_HL* p_evt_data,
   2873                                 tBTA_HL_APP_HANDLE app_handle,
   2874                                 tBTA_HL_MCL_HANDLE mcl_handle,
   2875                                 tBTA_HL_STATUS status) {
   2876   p_evt_data->echo_test_cfm.mcl_handle = mcl_handle;
   2877   p_evt_data->echo_test_cfm.app_handle = app_handle;
   2878   p_evt_data->echo_test_cfm.status = status;
   2879 }
   2880 
   2881 /*****************************************************************************
   2882  *  Debug Functions
   2883  ****************************************************************************/
   2884 #if (BTA_HL_DEBUG == TRUE)
   2885 
   2886 /*******************************************************************************
   2887  *
   2888  * Function         bta_hl_status_code
   2889  *
   2890  * Description      get the status string pointer
   2891  *
   2892  * Returns          char * - status string pointer
   2893  *
   2894  ******************************************************************************/
   2895 const char* bta_hl_status_code(tBTA_HL_STATUS status) {
   2896   switch (status) {
   2897     case BTA_HL_STATUS_OK:
   2898       return "BTA_HL_STATUS_OK";
   2899     case BTA_HL_STATUS_FAIL:
   2900       return "BTA_HL_STATUS_FAIL";
   2901     case BTA_HL_STATUS_ABORTED:
   2902       return "BTA_HL_STATUS_ABORTED";
   2903     case BTA_HL_STATUS_NO_RESOURCE:
   2904       return "BTA_HL_STATUS_NO_RESOURCE";
   2905     case BTA_HL_STATUS_LAST_ITEM:
   2906       return "BTA_HL_STATUS_LAST_ITEM";
   2907     case BTA_HL_STATUS_DUPLICATE_APP_ID:
   2908       return "BTA_HL_STATUS_DUPLICATE_APP_ID";
   2909     case BTA_HL_STATUS_INVALID_APP_HANDLE:
   2910       return "BTA_HL_STATUS_INVALID_APP_HANDLE";
   2911     case BTA_HL_STATUS_INVALID_MCL_HANDLE:
   2912       return "BTA_HL_STATUS_INVALID_MCL_HANDLE";
   2913     case BTA_HL_STATUS_MCAP_REG_FAIL:
   2914       return "BTA_HL_STATUS_MCAP_REG_FAIL";
   2915     case BTA_HL_STATUS_MDEP_CO_FAIL:
   2916       return "BTA_HL_STATUS_MDEP_CO_FAIL";
   2917     case BTA_HL_STATUS_ECHO_CO_FAIL:
   2918       return "BTA_HL_STATUS_ECHO_CO_FAIL";
   2919     case BTA_HL_STATUS_MDL_CFG_CO_FAIL:
   2920       return "BTA_HL_STATUS_MDL_CFG_CO_FAIL";
   2921     case BTA_HL_STATUS_SDP_NO_RESOURCE:
   2922       return "BTA_HL_STATUS_SDP_NO_RESOURCE";
   2923     case BTA_HL_STATUS_SDP_FAIL:
   2924       return "BTA_HL_STATUS_SDP_FAIL";
   2925     case BTA_HL_STATUS_NO_CCH:
   2926       return "BTA_HL_STATUS_NO_CCH";
   2927     case BTA_HL_STATUS_NO_MCL:
   2928       return "BTA_HL_STATUS_NO_MCL";
   2929 
   2930     case BTA_HL_STATUS_NO_FIRST_RELIABLE:
   2931       return "BTA_HL_STATUS_NO_FIRST_RELIABLE";
   2932     case BTA_HL_STATUS_INVALID_DCH_CFG:
   2933       return "BTA_HL_STATUS_INVALID_DCH_CFG";
   2934     case BTA_HL_STATUS_INVALID_BD_ADDR:
   2935       return "BTA_HL_STATUS_INVALID_BD_ADDR";
   2936     case BTA_HL_STATUS_INVALID_RECONNECT_CFG:
   2937       return "BTA_HL_STATUS_INVALID_RECONNECT_CFG";
   2938     case BTA_HL_STATUS_ECHO_TEST_BUSY:
   2939       return "BTA_HL_STATUS_ECHO_TEST_BUSY";
   2940     case BTA_HL_STATUS_INVALID_LOCAL_MDEP_ID:
   2941       return "BTA_HL_STATUS_INVALID_LOCAL_MDEP_ID";
   2942     case BTA_HL_STATUS_INVALID_MDL_ID:
   2943       return "BTA_HL_STATUS_INVALID_MDL_ID";
   2944     case BTA_HL_STATUS_NO_MDL_ID_FOUND:
   2945       return "BTA_HL_STATUS_NO_MDL_ID_FOUND";
   2946     case BTA_HL_STATUS_DCH_BUSY:
   2947       return "BTA_HL_STATUS_DCH_BUSY";
   2948     default:
   2949       return "Unknown status code";
   2950   }
   2951 }
   2952 /*******************************************************************************
   2953  *
   2954  * Function         bta_hl_evt_code
   2955  *
   2956  * Description      Maps HL event code to the corresponding event string
   2957  *
   2958  * Returns          string pointer for the associated event name
   2959  *
   2960  ******************************************************************************/
   2961 const char* bta_hl_evt_code(tBTA_HL_INT_EVT evt_code) {
   2962   switch (evt_code) {
   2963     case BTA_HL_CCH_OPEN_EVT:
   2964       return "BTA_HL_CCH_OPEN_EVT";
   2965     case BTA_HL_CCH_SDP_OK_EVT:
   2966       return "BTA_HL_CCH_SDP_OK_EVT";
   2967     case BTA_HL_CCH_SDP_FAIL_EVT:
   2968       return "BTA_HL_CCH_SDP_FAIL_EVT";
   2969     case BTA_HL_MCA_CONNECT_IND_EVT:
   2970       return "BTA_HL_MCA_CONNECT_IND_EVT";
   2971     case BTA_HL_MCA_DISCONNECT_IND_EVT:
   2972       return "BTA_HL_MCA_DISCONNECT_IND_EVT";
   2973 
   2974     case BTA_HL_CCH_CLOSE_EVT:
   2975       return "BTA_HL_CCH_CLOSE_EVT";
   2976     case BTA_HL_CCH_CLOSE_CMPL_EVT:
   2977       return "BTA_HL_CCH_CLOSE_CMPL_EVT";
   2978     case BTA_HL_DCH_OPEN_EVT:
   2979       return "BTA_HL_DCH_OPEN_EVT";
   2980     case BTA_HL_MCA_CREATE_IND_EVT:
   2981       return "BTA_HL_MCA_CREATE_IND_EVT";
   2982     case BTA_HL_MCA_CREATE_CFM_EVT:
   2983       return "BTA_HL_MCA_CREATE_CFM_EVT";
   2984     case BTA_HL_MCA_OPEN_IND_EVT:
   2985       return "BTA_HL_MCA_OPEN_IND_EVT";
   2986     case BTA_HL_MCA_OPEN_CFM_EVT:
   2987       return "BTA_HL_MCA_OPEN_CFM_EVT";
   2988     case BTA_HL_DCH_CLOSE_EVT:
   2989       return "BTA_HL_DCH_CLOSE_EVT";
   2990     case BTA_HL_MCA_CLOSE_IND_EVT:
   2991       return "BTA_HL_MCA_CLOSE_IND_EVT";
   2992     case BTA_HL_MCA_CLOSE_CFM_EVT:
   2993       return "BTA_HL_MCA_CLOSE_CFM_EVT";
   2994     case BTA_HL_API_SEND_DATA_EVT:
   2995       return "BTA_HL_API_SEND_DATA_EVT";
   2996     case BTA_HL_MCA_RCV_DATA_EVT:
   2997       return "BTA_HL_MCA_RCV_DATA_EVT";
   2998     case BTA_HL_DCH_CLOSE_CMPL_EVT:
   2999       return "BTA_HL_DCH_CLOSE_CMPL_EVT";
   3000 
   3001     case BTA_HL_API_ENABLE_EVT:
   3002       return "BTA_HL_API_ENABLE_EVT";
   3003     case BTA_HL_API_DISABLE_EVT:
   3004       return "BTA_HL_API_DISABLE_EVT";
   3005     case BTA_HL_API_UPDATE_EVT:
   3006       return "BTA_HL_API_UPDATE_EVT";
   3007     case BTA_HL_API_REGISTER_EVT:
   3008       return "BTA_HL_API_REGISTER_EVT";
   3009     case BTA_HL_API_DEREGISTER_EVT:
   3010       return "BTA_HL_API_DEREGISTER_EVT";
   3011 
   3012     case BTA_HL_API_CCH_OPEN_EVT:
   3013       return "BTA_HL_API_CCH_OPEN_EVT";
   3014 
   3015     case BTA_HL_API_CCH_CLOSE_EVT:
   3016       return "BTA_HL_API_CCH_CLOSE_EVT";
   3017     case BTA_HL_API_DCH_OPEN_EVT:
   3018       return "BTA_HL_API_DCH_OPEN_EVT";
   3019 
   3020     case BTA_HL_API_DCH_RECONNECT_EVT:
   3021       return "BTA_HL_API_DCH_RECONNECT_EVT";
   3022     case BTA_HL_API_DCH_CLOSE_EVT:
   3023       return "BTA_HL_API_DCH_CLOSE_EVT";
   3024     case BTA_HL_API_DELETE_MDL_EVT:
   3025       return "BTA_HL_API_DELETE_MDL_EVT";
   3026     case BTA_HL_API_DCH_ABORT_EVT:
   3027       return "BTA_HL_API_DCH_ABORT_EVT";
   3028 
   3029     case BTA_HL_DCH_RECONNECT_EVT:
   3030       return "BTA_HL_DCH_RECONNECT_EVT";
   3031     case BTA_HL_DCH_SDP_INIT_EVT:
   3032       return "BTA_HL_DCH_SDP_INIT_EVT";
   3033     case BTA_HL_DCH_SDP_FAIL_EVT:
   3034       return "BTA_HL_DCH_SDP_FAIL_EVT";
   3035     case BTA_HL_API_DCH_ECHO_TEST_EVT:
   3036       return "BTA_HL_API_DCH_ECHO_TEST_EVT";
   3037     case BTA_HL_DCH_CLOSE_ECHO_TEST_EVT:
   3038       return "BTA_HL_DCH_CLOSE_ECHO_TEST_EVT";
   3039     case BTA_HL_MCA_RECONNECT_IND_EVT:
   3040       return "BTA_HL_MCA_RECONNECT_IND_EVT";
   3041     case BTA_HL_MCA_RECONNECT_CFM_EVT:
   3042       return "BTA_HL_MCA_RECONNECT_CFM_EVT";
   3043     case BTA_HL_API_DCH_CREATE_RSP_EVT:
   3044       return "BTA_HL_API_DCH_CREATE_RSP_EVT";
   3045     case BTA_HL_DCH_ABORT_EVT:
   3046       return "BTA_HL_DCH_ABORT_EVT";
   3047     case BTA_HL_MCA_ABORT_IND_EVT:
   3048       return "BTA_HL_MCA_ABORT_IND_EVT";
   3049     case BTA_HL_MCA_ABORT_CFM_EVT:
   3050       return "BTA_HL_MCA_ABORT_CFM_EVT";
   3051     case BTA_HL_MCA_DELETE_IND_EVT:
   3052       return "BTA_HL_MCA_DELETE_IND_EVT";
   3053     case BTA_HL_MCA_DELETE_CFM_EVT:
   3054       return "BTA_HL_MCA_DELETE_CFM_EVT";
   3055     case BTA_HL_MCA_CONG_CHG_EVT:
   3056       return "BTA_HL_MCA_CONG_CHG_EVT";
   3057     case BTA_HL_CI_GET_TX_DATA_EVT:
   3058       return "BTA_HL_CI_GET_TX_DATA_EVT";
   3059     case BTA_HL_CI_PUT_RX_DATA_EVT:
   3060       return "BTA_HL_CI_PUT_RX_DATA_EVT";
   3061     case BTA_HL_CI_GET_ECHO_DATA_EVT:
   3062       return "BTA_HL_CI_GET_ECHO_DATA_EVT";
   3063     case BTA_HL_DCH_ECHO_TEST_EVT:
   3064       return "BTA_HL_DCH_ECHO_TEST_EVT";
   3065     case BTA_HL_CI_PUT_ECHO_DATA_EVT:
   3066       return "BTA_HL_CI_PUT_ECHO_DATA_EVT";
   3067     case BTA_HL_API_SDP_QUERY_EVT:
   3068       return "BTA_HL_API_SDP_QUERY_EVT";
   3069     case BTA_HL_SDP_QUERY_OK_EVT:
   3070       return "BTA_HL_SDP_QUERY_OK_EVT";
   3071     case BTA_HL_SDP_QUERY_FAIL_EVT:
   3072       return "BTA_HL_SDP_QUERY_FAIL_EVT";
   3073     case BTA_HL_MCA_RSP_TOUT_IND_EVT:
   3074       return "BTA_HL_MCA_RSP_TOUT_IND_EVT";
   3075 
   3076     default:
   3077       return "Unknown HL event code";
   3078   }
   3079 }
   3080 
   3081 #endif  /* Debug Functions */
   3082 #endif  // HL_INCLUDED
   3083