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