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