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