bta_hl_utils.c revision 8e90de46284238e551ad825fb00bda2bbc90ea1d
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_hl_int.h"
37#include "bta_hl_co.h"
38#include "mca_defs.h"
39#include "mca_api.h"
40
41
42/*******************************************************************************
43**
44** Function      bta_hl_set_ctrl_psm_for_dch
45**
46** Description    This function set the control PSM for the DCH setup
47**
48** Returns     BOOLEAN - TRUE - control PSM setting is successful
49*******************************************************************************/
50BOOLEAN bta_hl_set_ctrl_psm_for_dch(UINT8 app_idx, UINT8 mcl_idx,
51                                    UINT8 mdl_idx, UINT16 ctrl_psm)
52{
53    tBTA_HL_MCL_CB *p_mcb  = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
54    BOOLEAN success = TRUE, update_ctrl_psm = FALSE;
55    UNUSED(mdl_idx);
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_DEBUG("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_DEBUG("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 (HCI_ACL_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_DEBUG("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 (HCI_ACL_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 (HCI_ACL_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_DEBUG("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 (HCI_ACL_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_ERROR("The MPS is zero");
225            tx_win_size = 10;
226        }
227    }
228
229#if BTA_HL_DEBUG == TRUE
230    APPL_TRACE_DEBUG("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_DEBUG("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_DEBUG("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_DEBUG("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_ERROR("Inavlid echo cfg value");
439        }
440        return status;
441    }
442
443#if BTA_HL_DEBUG == TRUE
444    if (!status)
445    {
446        APPL_TRACE_DEBUG("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_ERROR("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_DEBUG("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_DEBUG("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_DEBUG("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_DEBUG("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_DEBUG("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_DEBUG("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_DEBUG("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_DEBUG("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_DEBUG("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_DEBUG("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_DEBUG("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_DEBUG("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_DEBUG("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_DEBUG("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_DEBUG("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 configuration 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    UNUSED(mcl_idx);
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_DEBUG("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
1465    *p_mdl_cfg_idx = 0;
1466    for (i=0; i< BTA_HL_NUM_MDL_CFGS; i++)
1467    {
1468        p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1469        if(p_mdl->active)
1470            APPL_TRACE_DEBUG("bta_hl_find_mdl_cfg_idx: mdl_id =%d, p_mdl->mdl_id=%d",mdl_id,
1471                              p_mdl->mdl_id);
1472        if (p_mdl->active &&
1473            (!memcmp (p_mcb->bd_addr, p_mdl->peer_bd_addr, BD_ADDR_LEN))&&
1474            (p_mdl->mdl_id == mdl_id))
1475        {
1476            found=TRUE;
1477            *p_mdl_cfg_idx =i;
1478            break;
1479        }
1480    }
1481
1482#if BTA_HL_DEBUG == TRUE
1483    if (!found)
1484    {
1485        APPL_TRACE_DEBUG("bta_hl_find_mdl_cfg_idx found=%d mdl_cfg_idx=%d ",found, i );
1486    }
1487#endif
1488
1489    return found;
1490
1491
1492}
1493
1494
1495/*******************************************************************************
1496**
1497** Function      bta_hl_get_cur_time
1498**
1499** Description  This function get the cuurent time value
1500**
1501** Returns      BOOLEAN - TRUE found
1502**                        FALSE not found
1503**
1504*******************************************************************************/
1505BOOLEAN  bta_hl_get_cur_time(UINT8 app_idx, UINT8 *p_cur_time)
1506{
1507    tBTA_HL_MDL_CFG     *p_mdl;
1508    UINT8 i, j, time_latest, time;
1509    BOOLEAN found=FALSE, result=TRUE;
1510
1511    for (i=0; i< BTA_HL_NUM_MDL_CFGS; i++)
1512    {
1513        p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1514        if (p_mdl->active)
1515        {
1516            found=TRUE;
1517            time_latest = p_mdl->time;
1518            for (j=(i+1); j< BTA_HL_NUM_MDL_CFGS; j++ )
1519            {
1520                p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, j);
1521                if (p_mdl->active)
1522                {
1523                    time = p_mdl->time;
1524                    if (time > time_latest)
1525                    {
1526                        time_latest = time;
1527                    }
1528                }
1529            }
1530            break;
1531        }
1532    }
1533
1534
1535    if (found)
1536    {
1537        if (time_latest < BTA_HL_MAX_TIME)
1538        {
1539            *p_cur_time = time_latest+1;
1540        }
1541        else
1542        {
1543            /* need to wrap around */
1544            result = FALSE;
1545        }
1546    }
1547    else
1548    {
1549        *p_cur_time = BTA_HL_MIN_TIME;
1550    }
1551
1552#if BTA_HL_DEBUG == TRUE
1553    if (!result)
1554    {
1555        APPL_TRACE_DEBUG("bta_hl_get_cur_time result=%s cur_time=%d",
1556                          (result?"OK":"FAIL"), *p_cur_time);
1557    }
1558#endif
1559
1560    return result;
1561}
1562
1563/*******************************************************************************
1564**
1565** Function      bta_hl_sort_cfg_time_idx
1566**
1567** Description  This function sort the mdl configuration idx stored in array a
1568**              based on decending time value
1569**
1570** Returns      BOOLEAN - TRUE found
1571**                        FALSE not found
1572**
1573*******************************************************************************/
1574void bta_hl_sort_cfg_time_idx(UINT8 app_idx, UINT8 *a, UINT8 n)
1575{
1576    tBTA_HL_APP_CB      *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1577    UINT8 temp_time, temp_idx;
1578    INT16 i, j;
1579    for (i = 1; i < n; ++i)
1580    {
1581        temp_idx = a[i];
1582        temp_time = p_acb->mdl_cfg[temp_idx].time;
1583        j = i - 1;
1584        while ((j >= 0) && (temp_time < p_acb->mdl_cfg[a[j]].time))
1585        {
1586            a[j + 1] = a[j];
1587            --j;
1588        }
1589        a[j + 1] = temp_idx;
1590    }
1591}
1592
1593/*******************************************************************************
1594**
1595** Function      bta_hl_compact_mdl_cfg_time
1596**
1597** Description  This function finds the MDL configuration index based on
1598**              the MDL ID
1599**
1600** Returns      BOOLEAN - TRUE found
1601**                        FALSE not found
1602**
1603*******************************************************************************/
1604void  bta_hl_compact_mdl_cfg_time(UINT8 app_idx, UINT8 mdep_id)
1605{
1606    tBTA_HL_APP_CB      *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1607    tBTA_HL_MDL_CFG     *p_mdl;
1608    UINT8 i, time_min, cnt=0;
1609    UINT8   s_arr[BTA_HL_NUM_MDL_CFGS];
1610
1611
1612    for (i=0; i< BTA_HL_NUM_MDL_CFGS; i++)
1613    {
1614        p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1615        if (p_mdl->active )
1616        {
1617            s_arr[cnt]= i;
1618            cnt++;
1619        }
1620    }
1621
1622
1623
1624#if BTA_HL_DEBUG == TRUE
1625    APPL_TRACE_DEBUG("bta_hl_compact_mdl_cfg_time cnt=%d ",cnt );
1626#endif
1627
1628
1629    if (cnt)
1630    {
1631        bta_hl_sort_cfg_time_idx(app_idx, s_arr, cnt);
1632        time_min = BTA_HL_MIN_TIME;
1633        for (i=0;i<cnt; i++)
1634        {
1635            p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, s_arr[i]);
1636            p_mdl->time = time_min + i;
1637            bta_hl_co_save_mdl(mdep_id, s_arr[i], p_mdl);
1638        }
1639    }
1640
1641
1642}
1643
1644
1645
1646/*******************************************************************************
1647**
1648** Function      bta_hl_is_mdl_exsit_in_mcl
1649**
1650** Description  This function checks whether the MDL ID
1651**              has already existed in teh MCL or not
1652**
1653** Returns      BOOLEAN - TRUE exist
1654**                        FALSE does not exist
1655**
1656*******************************************************************************/
1657BOOLEAN  bta_hl_is_mdl_exsit_in_mcl(UINT8 app_idx, BD_ADDR bd_addr,
1658                                    tBTA_HL_MDL_ID mdl_id)
1659{
1660    tBTA_HL_MDL_CFG     *p_mdl;
1661    BOOLEAN             found = FALSE;
1662    UINT8               i;
1663
1664    for (i = 0; i< BTA_HL_NUM_MDL_CFGS; i++)
1665    {
1666        p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1667        if (p_mdl->active &&
1668            !memcmp(p_mdl->peer_bd_addr, bd_addr,BD_ADDR_LEN))
1669        {
1670            if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS)
1671            {
1672                if (p_mdl->mdl_id == mdl_id)
1673                {
1674                    found = TRUE;
1675                    break;
1676                }
1677            }
1678            else
1679            {
1680                found = TRUE;
1681                break;
1682            }
1683        }
1684    }
1685
1686    return found;
1687}
1688
1689/*******************************************************************************
1690**
1691** Function      bta_hl_delete_mdl_cfg
1692**
1693** Description  This function delete the specified MDL ID
1694**
1695** Returns      BOOLEAN - TRUE Success
1696**                        FALSE Failed
1697**
1698*******************************************************************************/
1699BOOLEAN  bta_hl_delete_mdl_cfg(UINT8 app_idx, BD_ADDR bd_addr,
1700                               tBTA_HL_MDL_ID mdl_id)
1701{
1702    tBTA_HL_MDL_CFG     *p_mdl;
1703    BOOLEAN             success = FALSE;
1704    UINT8               i;
1705    tBTA_HL_APP_CB      *p_acb= BTA_HL_GET_APP_CB_PTR(app_idx);
1706    UINT8               app_id = p_acb->app_id;
1707
1708    for (i = 0; i< BTA_HL_NUM_MDL_CFGS; i++)
1709    {
1710        p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1711        if (p_mdl->active &&
1712            !memcmp(p_mdl->peer_bd_addr, bd_addr,BD_ADDR_LEN))
1713        {
1714            if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS)
1715            {
1716                if (p_mdl->mdl_id == mdl_id)
1717                {
1718                    bta_hl_co_delete_mdl(p_mdl->local_mdep_id, i);
1719                    memset(p_mdl, 0, sizeof(tBTA_HL_MDL_CFG));
1720                    success = TRUE;
1721                    break;
1722                }
1723            }
1724            else
1725            {
1726                bta_hl_co_delete_mdl(p_mdl->local_mdep_id, i);
1727                memset(p_mdl, 0, sizeof(tBTA_HL_MDL_CFG));
1728                success = TRUE;
1729            }
1730        }
1731    }
1732
1733    return success;
1734}
1735
1736
1737/*******************************************************************************
1738**
1739** Function      bta_hl_is_mdl_value_valid
1740**
1741**
1742** Description  This function checks the specified MDL ID is in valid range or not
1743**
1744** Returns      BOOLEAN - TRUE Success
1745**                        FALSE Failed
1746**
1747** note:   mdl_id range   0x0000 reserved,
1748**                        0x0001-oxFEFF dynamic range,
1749**                        0xFF00-0xFFFE reserved,
1750**                        0xFFFF indicates all MDLs (for delete operation only)
1751**
1752*******************************************************************************/
1753BOOLEAN  bta_hl_is_mdl_value_valid(tBTA_HL_MDL_ID mdl_id)
1754{
1755    BOOLEAN             status = TRUE;
1756
1757    if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS)
1758    {
1759        if (mdl_id != 0)
1760        {
1761            if (mdl_id > BTA_HL_MAX_MDL_VAL )
1762            {
1763                status = FALSE;
1764            }
1765        }
1766        else
1767        {
1768            status = FALSE;
1769        }
1770    }
1771
1772    return status;
1773}
1774
1775/*******************************************************************************
1776**
1777** Function      bta_hl_find_mdep_cfg_idx
1778**
1779** Description  This function finds the MDEP configuration index based
1780**                on the local MDEP ID
1781**
1782** Returns      BOOLEAN - TRUE found
1783**                        FALSE not found
1784**
1785*******************************************************************************/
1786BOOLEAN bta_hl_find_mdep_cfg_idx(UINT8 app_idx,  tBTA_HL_MDEP_ID local_mdep_id,
1787                                 UINT8 *p_mdep_cfg_idx)
1788{
1789    tBTA_HL_APP_CB      *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1790    tBTA_HL_SUP_FEATURE     *p_sup_feature= &p_acb->sup_feature;
1791    BOOLEAN found =FALSE;
1792    UINT8 i;
1793
1794    for (i=0; i< p_sup_feature->num_of_mdeps; i++)
1795    {
1796        if ( p_sup_feature->mdep[i].mdep_id == local_mdep_id)
1797        {
1798            found = TRUE;
1799            *p_mdep_cfg_idx = i;
1800            break;
1801        }
1802    }
1803
1804#if BTA_HL_DEBUG == TRUE
1805    if (!found)
1806    {
1807        APPL_TRACE_DEBUG("bta_hl_find_mdep_cfg_idx found=%d mdep_idx=%d local_mdep_id=%d ",
1808                          found,i, local_mdep_id );
1809    }
1810#endif
1811    return found;
1812}
1813
1814
1815/*******************************************************************************
1816**
1817** Function      bta_hl_find_rxtx_apdu_size
1818**
1819** Description  This function finds the maximum APDU rx and tx sizes based on
1820**              the MDEP configuration data
1821**
1822** Returns      void
1823**
1824*******************************************************************************/
1825void bta_hl_find_rxtx_apdu_size(UINT8 app_idx, UINT8 mdep_cfg_idx,
1826                                UINT16 *p_rx_apu_size,
1827                                UINT16 *p_tx_apu_size)
1828{
1829    tBTA_HL_APP_CB      *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1830    tBTA_HL_MDEP_CFG     *p_mdep_cfg;
1831    UINT8 i;
1832    UINT16 max_rx_apdu_size=0, max_tx_apdu_size=0;
1833
1834    p_mdep_cfg = &p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg;
1835
1836
1837    for (i=0; i< p_mdep_cfg->num_of_mdep_data_types ; i++)
1838    {
1839
1840        if (max_rx_apdu_size < p_mdep_cfg->data_cfg[i].max_rx_apdu_size)
1841        {
1842            max_rx_apdu_size = p_mdep_cfg->data_cfg[i].max_rx_apdu_size;
1843        }
1844
1845        if (max_tx_apdu_size < p_mdep_cfg->data_cfg[i].max_tx_apdu_size)
1846        {
1847            max_tx_apdu_size = p_mdep_cfg->data_cfg[i].max_tx_apdu_size;
1848        }
1849    }
1850
1851
1852    *p_rx_apu_size = max_rx_apdu_size;
1853    *p_tx_apu_size = max_tx_apdu_size;
1854
1855#if BTA_HL_DEBUG == TRUE
1856    APPL_TRACE_DEBUG("bta_hl_find_rxtx_apdu_size max_rx_apdu_size=%d max_tx_apdu_size=%d ",
1857                      max_rx_apdu_size, max_tx_apdu_size );
1858#endif
1859
1860
1861}
1862
1863/*******************************************************************************
1864**
1865** Function      bta_hl_validate_peer_cfg
1866**
1867** Description  This function validates the peer DCH configuration
1868**
1869** Returns      BOOLEAN - TRUE validation is successful
1870**                        FALSE validation failed
1871**
1872*******************************************************************************/
1873BOOLEAN bta_hl_validate_peer_cfg(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,
1874                                 tBTA_HL_MDEP_ID peer_mdep_id,
1875                                 tBTA_HL_MDEP_ROLE peer_mdep_role,
1876                                 UINT8 sdp_idx)
1877{
1878    tBTA_HL_MCL_CB      *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1879    tBTA_HL_MDL_CB      *p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
1880    tBTA_HL_SDP_REC     *p_rec;
1881    BOOLEAN peer_found =FALSE;
1882    UINT8 i;
1883
1884    APPL_TRACE_DEBUG("bta_hl_validate_peer_cfg sdp_idx=%d app_idx %d", sdp_idx, app_idx);
1885
1886
1887    if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID)
1888    {
1889        return TRUE;
1890    }
1891
1892    p_rec = &p_mcb->sdp.sdp_rec[sdp_idx];
1893    for (i=0; i< p_rec->num_mdeps; i++)
1894    {
1895        APPL_TRACE_DEBUG("mdep_id %d peer_mdep_id %d",p_rec->mdep_cfg[i].mdep_id , peer_mdep_id);
1896        APPL_TRACE_DEBUG("mdep_role %d peer_mdep_role %d",p_rec->mdep_cfg[i].mdep_role,
1897                          peer_mdep_role)
1898        if ( (p_rec->mdep_cfg[i].mdep_id == peer_mdep_id) &&
1899             (p_rec->mdep_cfg[i].mdep_role == peer_mdep_role))
1900        {
1901            peer_found = TRUE;
1902
1903            break;
1904        }
1905    }
1906
1907#if BTA_HL_DEBUG == TRUE
1908    if (!peer_found)
1909    {
1910        APPL_TRACE_DEBUG("bta_hl_validate_peer_cfg failed num_mdeps=%d",p_rec->num_mdeps);
1911    }
1912#endif
1913    return peer_found;
1914}
1915
1916/*******************************************************************************
1917**
1918** Function      bta_hl_chk_local_cfg
1919**
1920** Description  This function check whether the local DCH configuration is OK or not
1921**
1922** Returns      tBTA_HL_STATUS - OK - local DCH configuration is OK
1923**                               NO_FIRST_RELIABLE - the streaming DCH configuration
1924**                                                   is not OK and it needs to use
1925**                                                   reliable DCH configuration
1926**
1927*******************************************************************************/
1928tBTA_HL_STATUS bta_hl_chk_local_cfg(UINT8 app_idx, UINT8 mcl_idx,
1929                                    UINT8 mdep_cfg_idx,
1930                                    tBTA_HL_DCH_CFG local_cfg)
1931{
1932    tBTA_HL_APP_CB      *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1933    tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
1934
1935    if ( mdep_cfg_idx &&
1936         (p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg.mdep_role == BTA_HL_MDEP_ROLE_SOURCE) &&
1937         (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) &&
1938         (local_cfg != BTA_HL_DCH_CFG_RELIABLE))
1939    {
1940        status =  BTA_HL_STATUS_NO_FIRST_RELIABLE;
1941        APPL_TRACE_ERROR("BTA_HL_STATUS_INVALID_DCH_CFG");
1942    }
1943
1944    return status;
1945}
1946
1947
1948/*******************************************************************************
1949**
1950** Function      bta_hl_validate_reconnect_params
1951**
1952** Description  This function validates the reconnect parameters
1953**
1954** Returns      BOOLEAN - TRUE validation is successful
1955**                        FALSE validation failed
1956*******************************************************************************/
1957BOOLEAN bta_hl_validate_reconnect_params(UINT8 app_idx, UINT8 mcl_idx,
1958                                         tBTA_HL_API_DCH_RECONNECT *p_reconnect,
1959                                         UINT8 *p_mdep_cfg_idx, UINT8 *p_mdl_cfg_idx)
1960{
1961    tBTA_HL_APP_CB      *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1962    tBTA_HL_SUP_FEATURE *p_sup_feature = &p_acb->sup_feature;
1963    UINT8               num_mdeps;
1964    UINT8               mdl_cfg_idx;
1965    BOOLEAN local_mdep_id_found =FALSE;
1966    BOOLEAN mdl_cfg_found =FALSE;
1967    BOOLEAN            status=FALSE;
1968    UINT8 i, in_use_mdl_idx = 0;
1969
1970#if BTA_HL_DEBUG == TRUE
1971    APPL_TRACE_DEBUG("bta_hl_validate_reconnect_params  mdl_id=%d app_idx=%d", p_reconnect->mdl_id, app_idx);
1972#endif
1973    if (bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, p_reconnect->mdl_id, &mdl_cfg_idx))
1974    {
1975        mdl_cfg_found = TRUE;
1976    }
1977
1978#if BTA_HL_DEBUG == TRUE
1979    if (!mdl_cfg_found)
1980    {
1981        APPL_TRACE_DEBUG("mdl_cfg_found not found");
1982    }
1983#endif
1984
1985
1986    if (mdl_cfg_found)
1987    {
1988        num_mdeps = p_sup_feature->num_of_mdeps;
1989        for (i=0; i< num_mdeps ; i++)
1990        {
1991            if ( p_sup_feature->mdep[i].mdep_id == p_acb->mdl_cfg[mdl_cfg_idx].local_mdep_id)
1992            {
1993                local_mdep_id_found = TRUE;
1994                *p_mdep_cfg_idx =i;
1995                *p_mdl_cfg_idx = mdl_cfg_idx;
1996                break;
1997            }
1998        }
1999    }
2000
2001#if BTA_HL_DEBUG == TRUE
2002    if (!local_mdep_id_found)
2003    {
2004        APPL_TRACE_DEBUG("local_mdep_id not found");
2005    }
2006#endif
2007
2008
2009    if (local_mdep_id_found)
2010    {
2011        if (!bta_hl_find_mdl_idx(app_idx,mcl_idx, p_reconnect->mdl_id, &in_use_mdl_idx))
2012        {
2013            status= TRUE;
2014        }
2015        else
2016        {
2017            APPL_TRACE_ERROR("mdl_id=%d is curreltly in use",p_reconnect->mdl_id);
2018        }
2019    }
2020
2021#if BTA_HL_DEBUG == TRUE
2022    if (!status)
2023    {
2024        APPL_TRACE_DEBUG("Reconnect validation failed local_mdep_id found=%d mdl_cfg_idx found=%d in_use_mdl_idx=%d ",
2025                          local_mdep_id_found,  mdl_cfg_found, in_use_mdl_idx);
2026    }
2027#endif
2028    return status;
2029}
2030
2031/*******************************************************************************
2032**
2033** Function      bta_hl_find_avail_mcl_idx
2034**
2035** Returns      BOOLEAN - TRUE found
2036**                        FALSE not found
2037**
2038*******************************************************************************/
2039BOOLEAN bta_hl_find_avail_mcl_idx(UINT8 app_idx, UINT8 *p_mcl_idx)
2040{
2041    BOOLEAN found=FALSE;
2042    UINT8 i;
2043
2044    for (i=0; i < BTA_HL_NUM_MCLS ; i ++)
2045    {
2046        if (!bta_hl_cb.acb[app_idx].mcb[i].in_use)
2047        {
2048            found = TRUE;
2049            *p_mcl_idx = i;
2050            break;
2051        }
2052    }
2053
2054#if BTA_HL_DEBUG == TRUE
2055    if (!found)
2056    {
2057        APPL_TRACE_DEBUG("bta_hl_find_avail_mcl_idx found=%d idx=%d",
2058                          found, i);
2059    }
2060#endif
2061    return found;
2062}
2063
2064
2065
2066/*******************************************************************************
2067**
2068** Function      bta_hl_find_avail_mdl_idx
2069**
2070** Description  This function finds an available MDL control block index
2071**
2072** Returns      BOOLEAN - TRUE found
2073**                        FALSE not found
2074**
2075*******************************************************************************/
2076BOOLEAN bta_hl_find_avail_mdl_idx(UINT8 app_idx, UINT8 mcl_idx,
2077                                  UINT8 *p_mdl_idx)
2078{
2079    tBTA_HL_MCL_CB      *p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2080    BOOLEAN found=FALSE;
2081    UINT8 i;
2082
2083    for (i=0; i < BTA_HL_NUM_MDLS_PER_MCL ; i ++)
2084    {
2085        if (!p_mcb->mdl[i].in_use)
2086        {
2087            memset((void *)&p_mcb->mdl[i],0, sizeof(tBTA_HL_MDL_CB));
2088            found = TRUE;
2089            *p_mdl_idx = i;
2090            break;
2091        }
2092    }
2093
2094#if BTA_HL_DEBUG == TRUE
2095    if (!found)
2096    {
2097        APPL_TRACE_DEBUG("bta_hl_find_avail_mdl_idx found=%d idx=%d",
2098                          found, i);
2099    }
2100#endif
2101    return found;
2102}
2103
2104/*******************************************************************************
2105**
2106** Function      bta_hl_is_a_duplicate_id
2107**
2108** Description  This function finds the application has been used or not
2109**
2110** Returns      BOOLEAN - TRUE the app_id is a duplicate ID
2111**                        FALSE not a duplicate ID
2112*******************************************************************************/
2113BOOLEAN bta_hl_is_a_duplicate_id(UINT8 app_id)
2114{
2115    BOOLEAN is_duplicate=FALSE;
2116    UINT8 i;
2117
2118    for (i=0; i < BTA_HL_NUM_APPS ; i ++)
2119    {
2120        if (bta_hl_cb.acb[i].in_use &&
2121            (bta_hl_cb.acb[i].app_id == app_id))
2122        {
2123            is_duplicate = TRUE;
2124
2125            break;
2126        }
2127    }
2128
2129#if BTA_HL_DEBUG == TRUE
2130    if (is_duplicate)
2131    {
2132
2133        APPL_TRACE_DEBUG("bta_hl_is_a_duplicate_id app_id=%d is_duplicate=%d",
2134                          app_id, is_duplicate);
2135    }
2136#endif
2137
2138    return is_duplicate;
2139}
2140
2141
2142/*******************************************************************************
2143**
2144** Function      bta_hl_find_avail_app_idx
2145**
2146** Description  This function finds an available application control block index
2147**
2148** Returns      BOOLEAN - TRUE found
2149**                        FALSE not found
2150**
2151*******************************************************************************/
2152BOOLEAN bta_hl_find_avail_app_idx(UINT8 *p_idx)
2153{
2154    BOOLEAN found=FALSE;
2155    UINT8 i;
2156
2157    for (i=0; i < BTA_HL_NUM_APPS ; i ++)
2158    {
2159        if (!bta_hl_cb.acb[i].in_use)
2160        {
2161            found = TRUE;
2162            *p_idx = i;
2163            break;
2164        }
2165    }
2166
2167#if BTA_HL_DEBUG == TRUE
2168    if (!found)
2169    {
2170        APPL_TRACE_DEBUG("bta_hl_find_avail_app_idx found=%d app_idx=%d",
2171                          found, i);
2172    }
2173#endif
2174    return found;
2175}
2176
2177/*******************************************************************************
2178**
2179** Function      bta_hl_app_update
2180**
2181** Description  This function registers an HDP application MCAP and DP
2182**
2183** Returns      tBTA_HL_STATUS -registration status
2184**
2185*******************************************************************************/
2186tBTA_HL_STATUS bta_hl_app_update(UINT8 app_id, BOOLEAN is_register)
2187{
2188    tBTA_HL_STATUS  status = BTA_HL_STATUS_OK;
2189    tBTA_HL_APP_CB  *p_acb = BTA_HL_GET_APP_CB_PTR(0);
2190    tMCA_CS         mca_cs;
2191    UINT8           i, mdep_idx, num_of_mdeps;
2192    UINT8           mdep_counter = 0;
2193
2194
2195#if BTA_HL_DEBUG == TRUE
2196    APPL_TRACE_DEBUG("bta_hl_app_update app_id=%d", app_id);
2197#endif
2198
2199    if (is_register)
2200    {
2201        if ((status == BTA_HL_STATUS_OK) &&
2202        bta_hl_co_get_num_of_mdep(app_id, &num_of_mdeps))
2203        {
2204            for (i=0; i < num_of_mdeps; i++)
2205            {
2206                mca_cs.type = MCA_TDEP_DATA;
2207                mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP;
2208                mca_cs.p_data_cback = bta_hl_mcap_data_cback;
2209                /* Find the first available mdep index, and create a MDL Endpoint */
2210                // make a function later if needed
2211                for (mdep_idx = 1; mdep_idx < BTA_HL_NUM_MDEPS; mdep_idx++)
2212                {
2213                    if ( p_acb->sup_feature.mdep[mdep_idx].mdep_id == 0)
2214                    {
2215                        break; /* We found an available index */
2216                    }
2217                    else
2218                    {
2219                        mdep_counter++;
2220                    }
2221                }
2222                /* If no available MDEPs, return error */
2223                if (mdep_idx == BTA_HL_NUM_MDEPS)
2224                {
2225                    APPL_TRACE_ERROR("bta_hl_app_update: Out of MDEP IDs");
2226                    status = BTA_HL_STATUS_MCAP_REG_FAIL;
2227                    break;
2228                }
2229                if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle,
2230                              &(p_acb->sup_feature.mdep[mdep_idx].mdep_id), &mca_cs) == MCA_SUCCESS)
2231                {
2232                    if (bta_hl_co_get_mdep_config(app_id,
2233                                                  mdep_idx,
2234                                                  mdep_counter,
2235                                                  p_acb->sup_feature.mdep[mdep_idx].mdep_id,
2236                                                  &p_acb->sup_feature.mdep[mdep_idx].mdep_cfg))
2237                    {
2238                        p_acb->sup_feature.mdep[mdep_idx].ori_app_id = app_id;
2239                        APPL_TRACE_DEBUG("mdep idx %d id %d ori_app_id %d num data type %d",mdep_idx,
2240                               p_acb->sup_feature.mdep[mdep_idx].mdep_id,
2241                               p_acb->sup_feature.mdep[mdep_idx].ori_app_id,
2242                               p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.num_of_mdep_data_types);
2243                        if (p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role ==
2244                            BTA_HL_MDEP_ROLE_SOURCE)
2245                        {
2246                            p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SOURCE;
2247                        }
2248                        else if (p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role ==
2249                                 BTA_HL_MDEP_ROLE_SINK)
2250                        {
2251                            p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SINK;
2252                        }
2253                        else
2254                        {
2255                            APPL_TRACE_ERROR("bta_hl_app_registration: Invalid Role %d",
2256                                            p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role);
2257                            status = BTA_HL_STATUS_MDEP_CO_FAIL;
2258                            break;
2259                        }
2260                    }
2261                    else
2262                    {
2263                        APPL_TRACE_ERROR("bta_hl_app_registration: Cfg callout failed");
2264                        status = BTA_HL_STATUS_MDEP_CO_FAIL;
2265                        break;
2266                    }
2267                }
2268                else
2269                {
2270                    APPL_TRACE_ERROR("bta_hl_app_registration: MCA_CreateDep failed");
2271                    status = BTA_HL_STATUS_MCAP_REG_FAIL;
2272                    break;
2273                }
2274
2275            }
2276            p_acb->sup_feature.num_of_mdeps += num_of_mdeps;
2277            APPL_TRACE_DEBUG("num_of_mdeps %d", p_acb->sup_feature.num_of_mdeps);
2278
2279            if ((status == BTA_HL_STATUS_OK) &&
2280                (p_acb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SOURCE))
2281            {
2282                p_acb->sup_feature.advertize_source_sdp =
2283                bta_hl_co_advrtise_source_sdp(app_id);
2284            }
2285
2286            if ((status == BTA_HL_STATUS_OK)&&
2287                (!bta_hl_co_get_echo_config(app_id, &p_acb->sup_feature.echo_cfg)))
2288            {
2289                status = BTA_HL_STATUS_ECHO_CO_FAIL;
2290            }
2291
2292            if ((status == BTA_HL_STATUS_OK)&&
2293                (!bta_hl_co_load_mdl_config(app_id, BTA_HL_NUM_MDL_CFGS, &p_acb->mdl_cfg[0])))
2294            {
2295                status = BTA_HL_STATUS_MDL_CFG_CO_FAIL;
2296            }
2297        }
2298        else
2299        {
2300            status = BTA_HL_STATUS_MDEP_CO_FAIL;
2301        }
2302    }
2303    else
2304    {
2305        for (i=1; i<BTA_HL_NUM_MDEPS; i++)
2306        {
2307            if (p_acb->sup_feature.mdep[i].ori_app_id == app_id)
2308            {
2309                APPL_TRACE_DEBUG("Found index %", i);
2310
2311
2312                if (MCA_DeleteDep((tMCA_HANDLE)p_acb->app_handle,
2313                                  (p_acb->sup_feature.mdep[i].mdep_id)) != MCA_SUCCESS)
2314                {
2315                    APPL_TRACE_ERROR("Error deregistering");
2316                    status = BTA_HL_STATUS_MCAP_REG_FAIL;
2317                    return status;
2318                }
2319                memset(&p_acb->sup_feature.mdep[i], 0, sizeof(tBTA_HL_MDEP));
2320            }
2321        }
2322
2323
2324    }
2325
2326    if (status == BTA_HL_STATUS_OK)
2327    {
2328        /* Register/Update MDEP(s) in SDP Record */
2329        status = bta_hl_sdp_update(app_id);
2330    }
2331    /* else do cleanup */
2332
2333
2334    return status;
2335}
2336
2337
2338/*******************************************************************************
2339**
2340** Function      bta_hl_app_registration
2341**
2342** Description  This function registers an HDP application MCAP and DP
2343**
2344** Returns      tBTA_HL_STATUS -registration status
2345**
2346*******************************************************************************/
2347tBTA_HL_STATUS bta_hl_app_registration(UINT8 app_idx)
2348{
2349    tBTA_HL_STATUS  status = BTA_HL_STATUS_OK;
2350    tBTA_HL_APP_CB  *p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
2351    tMCA_REG        reg;
2352    tMCA_CS         mca_cs;
2353    UINT8           i, num_of_mdeps;
2354    UINT8           mdep_counter = 0;
2355
2356#if BTA_HL_DEBUG == TRUE
2357    APPL_TRACE_DEBUG("bta_hl_app_registration app_idx=%d", app_idx);
2358#endif
2359
2360    reg.ctrl_psm = p_acb->ctrl_psm;
2361    reg.data_psm = p_acb->data_psm;
2362    reg.sec_mask = p_acb->sec_mask;
2363    reg.rsp_tout = BTA_HL_MCAP_RSP_TOUT;
2364
2365    if ( (p_acb->app_handle = (tBTA_HL_APP_HANDLE) MCA_Register(&reg, bta_hl_mcap_ctrl_cback))!=0)
2366    {
2367        mca_cs.type = MCA_TDEP_ECHO;
2368        mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP;
2369        mca_cs.p_data_cback = bta_hl_mcap_data_cback;
2370
2371        if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle,
2372                          &(p_acb->sup_feature.mdep[0].mdep_id),
2373                          &mca_cs) == MCA_SUCCESS)
2374        {
2375            if (p_acb->sup_feature.mdep[0].mdep_id != BTA_HL_ECHO_TEST_MDEP_ID)
2376            {
2377                status = BTA_HL_STATUS_MCAP_REG_FAIL;
2378                APPL_TRACE_ERROR("BAD MDEP ID for echo test mdep_id=%d",
2379                                  p_acb->sup_feature.mdep[0].mdep_id );
2380            }
2381        }
2382        else
2383        {
2384            status = BTA_HL_STATUS_MCAP_REG_FAIL;
2385            APPL_TRACE_ERROR("MCA_CreateDep for echo test(mdep_id=0) failed");
2386        }
2387
2388
2389        if ((status == BTA_HL_STATUS_OK) &&
2390            bta_hl_co_get_num_of_mdep(p_acb->app_id, &num_of_mdeps))
2391        {
2392            p_acb->sup_feature.num_of_mdeps = num_of_mdeps+1;
2393
2394            for (i=1; i<p_acb->sup_feature.num_of_mdeps; i++)
2395            {
2396                mca_cs.type = MCA_TDEP_DATA;
2397                mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP;
2398                mca_cs.p_data_cback = bta_hl_mcap_data_cback;
2399
2400                if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle,
2401                                  &(p_acb->sup_feature.mdep[i].mdep_id), &mca_cs) == MCA_SUCCESS)
2402                {
2403                    if (bta_hl_co_get_mdep_config(p_acb->app_id,
2404                                                  i,mdep_counter,
2405                                                  p_acb->sup_feature.mdep[i].mdep_id,
2406                                                  &p_acb->sup_feature.mdep[i].mdep_cfg))
2407                    {
2408                        if (p_acb->sup_feature.mdep[i].mdep_cfg.mdep_role == BTA_HL_MDEP_ROLE_SOURCE)
2409                        {
2410                            p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SOURCE;
2411                        }
2412                        else if (p_acb->sup_feature.mdep[i].mdep_cfg.mdep_role == BTA_HL_MDEP_ROLE_SINK)
2413                        {
2414                            p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SINK;
2415                        }
2416                        else
2417                        {
2418                            status = BTA_HL_STATUS_MDEP_CO_FAIL;
2419                            break;
2420                        }
2421                        p_acb->sup_feature.mdep[i].ori_app_id = p_acb->app_id;
2422                        APPL_TRACE_DEBUG("index %d ori_app_id %d", i,
2423                                          p_acb->sup_feature.mdep[i].ori_app_id);
2424                    }
2425                    else
2426                    {
2427                        status = BTA_HL_STATUS_MDEP_CO_FAIL;
2428                        break;
2429                    }
2430                }
2431                else
2432                {
2433                    status = BTA_HL_STATUS_MCAP_REG_FAIL;
2434                    break;
2435                }
2436            }
2437
2438
2439
2440            if ((status == BTA_HL_STATUS_OK) &&
2441                (p_acb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SOURCE))
2442            {
2443                /* this is a source only applciation */
2444                p_acb->sup_feature.advertize_source_sdp =
2445                bta_hl_co_advrtise_source_sdp(p_acb->app_id);
2446            }
2447
2448            if ((status == BTA_HL_STATUS_OK)&&
2449                (!bta_hl_co_get_echo_config(p_acb->app_id, &p_acb->sup_feature.echo_cfg)))
2450            {
2451                status = BTA_HL_STATUS_ECHO_CO_FAIL;
2452            }
2453
2454            if ((status == BTA_HL_STATUS_OK)&&
2455                (!bta_hl_co_load_mdl_config(p_acb->app_id, BTA_HL_NUM_MDL_CFGS, &p_acb->mdl_cfg[0])))
2456            {
2457                status = BTA_HL_STATUS_MDL_CFG_CO_FAIL;
2458            }
2459        }
2460        else
2461        {
2462            status = BTA_HL_STATUS_MDEP_CO_FAIL;
2463        }
2464    }
2465    else
2466    {
2467        status = BTA_HL_STATUS_MCAP_REG_FAIL;
2468    }
2469
2470    if (status == BTA_HL_STATUS_OK)
2471    {
2472        status = bta_hl_sdp_register(app_idx);
2473    }
2474
2475    return status;
2476}
2477
2478
2479/*******************************************************************************
2480**
2481** Function         bta_hl_discard_data
2482**
2483** Description  This function discard an HDP event
2484**
2485** Returns     void
2486**
2487*******************************************************************************/
2488void bta_hl_discard_data(UINT16 event, tBTA_HL_DATA *p_data)
2489{
2490
2491#if BTA_HL_DEBUG == TRUE
2492    APPL_TRACE_ERROR("BTA HL Discard event=%s",bta_hl_evt_code(event));
2493
2494#endif
2495
2496    switch (event)
2497    {
2498        case BTA_HL_API_SEND_DATA_EVT:
2499            break;
2500
2501        case BTA_HL_MCA_RCV_DATA_EVT:
2502            utl_freebuf((void**)&p_data->mca_rcv_data_evt.p_pkt);
2503            break;
2504
2505        default:
2506            /*Nothing to free*/
2507            break;
2508    }
2509}
2510
2511/*******************************************************************************
2512**
2513** Function         bta_hl_save_mdl_cfg
2514**
2515** Description    This function saves the MDL configuration
2516**
2517** Returns     void
2518**
2519*******************************************************************************/
2520void bta_hl_save_mdl_cfg(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx )
2521{
2522    tBTA_HL_APP_CB      *p_acb  = BTA_HL_GET_APP_CB_PTR(app_idx);
2523    tBTA_HL_MCL_CB      *p_mcb  = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2524    tBTA_HL_MDL_CB      *p_dcb  = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2525    UINT8 mdl_cfg_idx;
2526    tBTA_HL_MDL_ID mdl_id;
2527    BOOLEAN      found=TRUE;
2528    tBTA_HL_MDL_CFG mdl_cfg;
2529    tBTA_HL_MDEP *p_mdep_cfg;
2530    tBTA_HL_L2CAP_CFG_INFO l2cap_cfg;
2531    UINT8 time_val = 0;
2532    mdl_id = p_dcb->mdl_id;
2533    if (!bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, mdl_id, &mdl_cfg_idx))
2534    {
2535        if (!bta_hl_find_avail_mdl_cfg_idx(app_idx, mcl_idx, &mdl_cfg_idx))
2536        {
2537            APPL_TRACE_ERROR("No space to save the MDL config");
2538            found= FALSE; /*no space available*/
2539        }
2540    }
2541
2542    if (found)
2543    {
2544        bta_hl_get_l2cap_cfg(p_dcb->mdl_handle, &l2cap_cfg);
2545        if (!bta_hl_get_cur_time(app_idx, &time_val ))
2546        {
2547            bta_hl_compact_mdl_cfg_time(app_idx,p_dcb->local_mdep_id);
2548            bta_hl_get_cur_time(app_idx, &time_val);
2549        }
2550        mdl_cfg.active = TRUE;
2551        mdl_cfg.time = time_val;
2552        mdl_cfg.mdl_id  = p_dcb->mdl_id;
2553        mdl_cfg.dch_mode = p_dcb->dch_mode;
2554        mdl_cfg.mtu = l2cap_cfg.mtu;
2555        mdl_cfg.fcs = l2cap_cfg.fcs;
2556
2557        bdcpy(mdl_cfg.peer_bd_addr, p_mcb->bd_addr);
2558        mdl_cfg.local_mdep_id= p_dcb->local_mdep_id;
2559        p_mdep_cfg = &p_acb->sup_feature.mdep[p_dcb->local_mdep_cfg_idx];
2560        mdl_cfg.local_mdep_role= p_mdep_cfg->mdep_cfg.mdep_role;
2561        memcpy(&p_acb->mdl_cfg[mdl_cfg_idx], &mdl_cfg, sizeof(tBTA_HL_MDL_CFG));
2562        bta_hl_co_save_mdl(mdl_cfg.local_mdep_id, mdl_cfg_idx, &mdl_cfg);
2563    }
2564
2565#if BTA_HL_DEBUG == TRUE
2566    if (found)
2567    {
2568        if (p_dcb->mtu != l2cap_cfg.mtu)
2569        {
2570            APPL_TRACE_WARNING("MCAP and L2CAP peer mtu size out of sync from MCAP mtu=%d from l2cap mtu=%d",
2571                                p_dcb->mtu, l2cap_cfg.mtu);
2572        }
2573        APPL_TRACE_DEBUG("bta_hl_save_mdl_cfg saved=%d", found);
2574        APPL_TRACE_DEBUG("Saved. L2cap cfg mdl_id=%d mtu=%d fcs=%d dch_mode=%d",
2575                          mdl_cfg.mdl_id, mdl_cfg.mtu, mdl_cfg.fcs,  mdl_cfg.dch_mode);
2576    }
2577#endif
2578
2579
2580
2581}
2582
2583/*******************************************************************************
2584**
2585** Function      bta_hl_set_dch_chan_cfg
2586**
2587** Description    This function setups the L2CAP DCH channel configuration
2588**
2589** Returns     void
2590*******************************************************************************/
2591void bta_hl_set_dch_chan_cfg(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx,tBTA_HL_DATA *p_data)
2592{
2593    tBTA_HL_APP_CB *p_acb  = BTA_HL_GET_APP_CB_PTR(app_idx);
2594    tBTA_HL_MDL_CB *p_dcb  = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2595    UINT8 l2cap_mode = L2CAP_FCR_ERTM_MODE;
2596    tBTA_HL_SUP_FEATURE *p_sup_feature= &p_acb->sup_feature;
2597    UINT8 local_mdep_cfg_idx = p_dcb->local_mdep_cfg_idx;
2598
2599    switch (p_dcb->dch_oper)
2600    {
2601        case BTA_HL_DCH_OP_LOCAL_RECONNECT:
2602        case BTA_HL_DCH_OP_REMOTE_RECONNECT:
2603            if (p_dcb->dch_mode  == BTA_HL_DCH_MODE_STREAMING)
2604                l2cap_mode = L2CAP_FCR_STREAM_MODE;
2605            break;
2606        case BTA_HL_DCH_OP_LOCAL_OPEN:
2607            if (p_data->mca_evt.mca_data.create_cfm.cfg == BTA_HL_DCH_CFG_STREAMING)
2608                l2cap_mode = L2CAP_FCR_STREAM_MODE;
2609            break;
2610        case BTA_HL_DCH_OP_REMOTE_OPEN:
2611            if (p_dcb->local_cfg == BTA_HL_DCH_CFG_STREAMING )
2612                l2cap_mode = L2CAP_FCR_STREAM_MODE;
2613            break;
2614        default:
2615            APPL_TRACE_ERROR("Invalid dch oper=%d for set dch chan cfg", p_dcb->dch_oper);
2616            break;
2617    }
2618    p_dcb->chnl_cfg.fcr_opt.mode        = l2cap_mode;
2619    p_dcb->chnl_cfg.fcr_opt.mps         = bta_hl_set_mps(p_dcb->max_rx_apdu_size);
2620    p_dcb->chnl_cfg.fcr_opt.tx_win_sz   = bta_hl_set_tx_win_size(p_dcb->max_rx_apdu_size,
2621                                                                 p_dcb->chnl_cfg.fcr_opt.mps);
2622    p_dcb->chnl_cfg.fcr_opt.max_transmit= BTA_HL_L2C_MAX_TRANSMIT;
2623    p_dcb->chnl_cfg.fcr_opt.rtrans_tout = BTA_HL_L2C_RTRANS_TOUT;
2624    p_dcb->chnl_cfg.fcr_opt.mon_tout    = BTA_HL_L2C_MON_TOUT;
2625
2626    p_dcb->chnl_cfg.user_rx_pool_id     = bta_hl_set_user_rx_pool_id(p_dcb->max_rx_apdu_size);
2627    p_dcb->chnl_cfg.user_tx_pool_id     = bta_hl_set_user_tx_pool_id(p_dcb->max_tx_apdu_size);
2628    p_dcb->chnl_cfg.fcr_rx_pool_id      = BTA_HL_L2C_FCR_RX_POOL_ID;
2629    p_dcb->chnl_cfg.fcr_tx_pool_id      = BTA_HL_L2C_FCR_TX_POOL_ID;
2630    p_dcb->chnl_cfg.data_mtu            = p_dcb->max_rx_apdu_size;
2631
2632    p_dcb->chnl_cfg.fcs = BTA_HL_MCA_NO_FCS;
2633    if (local_mdep_cfg_idx !=  BTA_HL_ECHO_TEST_MDEP_CFG_IDX)
2634    {
2635        if (p_sup_feature->mdep[local_mdep_cfg_idx].mdep_cfg.mdep_role ==
2636            BTA_HL_MDEP_ROLE_SOURCE)
2637        {
2638            p_dcb->chnl_cfg.fcs = BTA_HL_DEFAULT_SOURCE_FCS;
2639        }
2640    }
2641    else
2642    {
2643        p_dcb->chnl_cfg.fcs = BTA_HL_MCA_USE_FCS;
2644    }
2645
2646#if BTA_HL_DEBUG == TRUE
2647    APPL_TRACE_DEBUG("L2CAP Params l2cap_mode[3-ERTM 4-STREAM]=%d", l2cap_mode);
2648    APPL_TRACE_DEBUG("Use FCS =%s mtu=%d", ((p_dcb->chnl_cfg.fcs & 1)?"YES":"NO"),
2649                      p_dcb->chnl_cfg.data_mtu);
2650    APPL_TRACE_DEBUG("tx_win_sz=%d, max_transmit=%d, rtrans_tout=%d, mon_tout=%d, mps=%d",
2651                      p_dcb->chnl_cfg.fcr_opt.tx_win_sz,
2652                      p_dcb->chnl_cfg.fcr_opt.max_transmit,
2653                      p_dcb->chnl_cfg.fcr_opt.rtrans_tout,
2654                      p_dcb->chnl_cfg.fcr_opt.mon_tout,
2655                      p_dcb->chnl_cfg.fcr_opt.mps);
2656
2657    APPL_TRACE_DEBUG("USER rx_pool_id=%d, tx_pool_id=%d, FCR rx_pool_id=%d, tx_pool_id=%d",
2658                      p_dcb->chnl_cfg.user_rx_pool_id,
2659                      p_dcb->chnl_cfg.user_tx_pool_id,
2660                      p_dcb->chnl_cfg.fcr_rx_pool_id,
2661                      p_dcb->chnl_cfg.fcr_tx_pool_id);
2662
2663#endif
2664
2665
2666
2667
2668
2669
2670
2671
2672}
2673
2674/*******************************************************************************
2675**
2676** Function      bta_hl_get_l2cap_cfg
2677**
2678** Description    This function get the current L2CAP channel configuration
2679**
2680** Returns     BOOLEAN - TRUE - operation is successful
2681*******************************************************************************/
2682BOOLEAN bta_hl_get_l2cap_cfg(tBTA_HL_MDL_HANDLE mdl_hnd, tBTA_HL_L2CAP_CFG_INFO *p_cfg)
2683{
2684    BOOLEAN success = FALSE;
2685    UINT16 lcid;
2686    tL2CAP_CFG_INFO *p_our_cfg;
2687    tL2CAP_CH_CFG_BITS our_cfg_bits;
2688    tL2CAP_CFG_INFO *p_peer_cfg;
2689    tL2CAP_CH_CFG_BITS peer_cfg_bits;
2690
2691    lcid = MCA_GetL2CapChannel((tMCA_DL) mdl_hnd);
2692    if ( lcid &&
2693         L2CA_GetCurrentConfig(lcid, &p_our_cfg, &our_cfg_bits, &p_peer_cfg,
2694                               &peer_cfg_bits))
2695    {
2696        p_cfg->fcs = BTA_HL_MCA_NO_FCS;
2697        if (our_cfg_bits & L2CAP_CH_CFG_MASK_FCS)
2698        {
2699            p_cfg->fcs |= p_our_cfg->fcs;
2700        }
2701        else
2702        {
2703            p_cfg->fcs = BTA_HL_MCA_USE_FCS;
2704        }
2705
2706        if (p_cfg->fcs != BTA_HL_MCA_USE_FCS )
2707        {
2708            if (peer_cfg_bits & L2CAP_CH_CFG_MASK_FCS)
2709            {
2710                p_cfg->fcs |= p_peer_cfg->fcs;
2711            }
2712            else
2713            {
2714                p_cfg->fcs = BTA_HL_MCA_USE_FCS;
2715            }
2716        }
2717
2718        p_cfg->mtu =0;
2719        if (peer_cfg_bits & L2CAP_CH_CFG_MASK_MTU)
2720        {
2721            p_cfg->mtu = p_peer_cfg->mtu;
2722        }
2723        else
2724        {
2725            p_cfg->mtu = L2CAP_DEFAULT_MTU;
2726        }
2727        success = TRUE;
2728    }
2729    else
2730    {
2731      p_cfg->mtu = L2CAP_DEFAULT_MTU;
2732      p_cfg->fcs = BTA_HL_L2C_NO_FCS;
2733    }
2734
2735#if BTA_HL_DEBUG == TRUE
2736    if (!success)
2737    {
2738        APPL_TRACE_DEBUG("bta_hl_get_l2cap_cfg success=%d mdl=%d lcid=%d", success, mdl_hnd, lcid);
2739        APPL_TRACE_DEBUG("l2cap mtu=%d fcs=%d", p_cfg->mtu, p_cfg->fcs);
2740    }
2741#endif
2742
2743    return success;
2744}
2745
2746/*******************************************************************************
2747**
2748** Function      bta_hl_validate_chan_cfg
2749**
2750** Description    This function validates the L2CAP channel configuration
2751**
2752** Returns     BOOLEAN - TRUE - validation is successful
2753*******************************************************************************/
2754BOOLEAN bta_hl_validate_chan_cfg(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx)
2755{
2756    tBTA_HL_APP_CB *p_acb  = BTA_HL_GET_APP_CB_PTR(app_idx);
2757    tBTA_HL_MDL_CB *p_dcb  = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2758    BOOLEAN success = FALSE;
2759    UINT8 mdl_cfg_idx = 0;
2760    tBTA_HL_L2CAP_CFG_INFO l2cap_cfg;
2761    BOOLEAN get_l2cap_result, get_mdl_result;
2762
2763    get_l2cap_result = bta_hl_get_l2cap_cfg(p_dcb->mdl_handle, &l2cap_cfg);
2764    get_mdl_result = bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, p_dcb->mdl_id, &mdl_cfg_idx);
2765
2766    if (get_l2cap_result && get_mdl_result)
2767    {
2768        if ((p_acb->mdl_cfg[mdl_cfg_idx].mtu <= l2cap_cfg.mtu) &&
2769            (p_acb->mdl_cfg[mdl_cfg_idx].fcs == l2cap_cfg.fcs) &&
2770            (p_acb->mdl_cfg[mdl_cfg_idx].dch_mode == p_dcb->dch_mode))
2771        {
2772            success = TRUE;
2773        }
2774    }
2775
2776
2777#if BTA_HL_DEBUG == TRUE
2778
2779    if (p_dcb->mtu != l2cap_cfg.mtu)
2780    {
2781        APPL_TRACE_WARNING("MCAP and L2CAP peer mtu size out of sync from MCAP mtu=%d from l2cap mtu=%d",
2782                            p_dcb->mtu, l2cap_cfg.mtu);
2783    }
2784
2785    if (!success)
2786    {
2787        APPL_TRACE_DEBUG("bta_hl_validate_chan_cfg success=%d app_idx=%d mcl_idx=%d mdl_idx=%d",success, app_idx, mcl_idx, mdl_idx);
2788        APPL_TRACE_DEBUG("Cur. L2cap cfg mtu=%d fcs=%d dch_mode=%d", l2cap_cfg.mtu, l2cap_cfg.fcs, p_dcb->dch_mode);
2789        APPL_TRACE_DEBUG("From saved: L2cap cfg mtu=%d fcs=%d dch_mode=%d", p_acb->mdl_cfg[mdl_cfg_idx].mtu,
2790                          p_acb->mdl_cfg[mdl_cfg_idx].fcs , p_acb->mdl_cfg[mdl_cfg_idx].dch_mode);
2791    }
2792#endif
2793
2794    return success;
2795}
2796
2797
2798/*******************************************************************************
2799**
2800** Function      bta_hl_is_cong_on
2801**
2802** Description    This function checks whether the congestion condition is on or not
2803**
2804** Returns      BOOLEAN - TRUE DCH is congested
2805**                        FALSE not congested
2806**
2807*******************************************************************************/
2808BOOLEAN  bta_hl_is_cong_on(UINT8 app_id, BD_ADDR bd_addr, tBTA_HL_MDL_ID mdl_id)
2809
2810{
2811    tBTA_HL_MDL_CB      *p_dcb;
2812    UINT8   app_idx = 0, mcl_idx, mdl_idx;
2813    BOOLEAN cong_status = TRUE;
2814
2815    if (bta_hl_find_app_idx(app_id, &app_idx))
2816    {
2817        if (bta_hl_find_mcl_idx(app_idx, bd_addr, &mcl_idx ))
2818        {
2819            if (bta_hl_find_mdl_idx(app_idx, mcl_idx, mdl_id, &mdl_idx ))
2820            {
2821                p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2822                cong_status  = p_dcb->cong;
2823            }
2824        }
2825    }
2826
2827    return cong_status;
2828}
2829
2830/*******************************************************************************
2831**
2832** Function      bta_hl_check_cch_close
2833**
2834** Description   This function checks whether there is a pending CCH close request
2835**               or not
2836**
2837** Returns      void
2838*******************************************************************************/
2839void bta_hl_check_cch_close(UINT8 app_idx, UINT8 mcl_idx, tBTA_HL_DATA *p_data, BOOLEAN check_dch_setup )
2840{
2841    tBTA_HL_MCL_CB      *p_mcb  = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2842    tBTA_HL_MDL_CB      *p_dcb;
2843    UINT8               mdl_idx;
2844
2845#if (BTA_HL_DEBUG == TRUE)
2846    APPL_TRACE_DEBUG("bta_hl_check_cch_close cch_close_dch_oper=%d",p_mcb->cch_close_dch_oper );
2847#endif
2848
2849    if (p_mcb->cch_oper == BTA_HL_CCH_OP_LOCAL_CLOSE)
2850    {
2851        if (check_dch_setup && bta_hl_find_dch_setup_mdl_idx(app_idx, mcl_idx, &mdl_idx))
2852        {
2853            p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2854            if (!p_mcb->rsp_tout)
2855            {
2856                p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_ABORT;
2857
2858                if (!p_dcb->abort_oper)
2859                {
2860                    p_dcb->abort_oper |= BTA_HL_ABORT_CCH_CLOSE_MASK;
2861                    bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_ABORT_EVT, p_data);
2862                }
2863            }
2864            else
2865            {
2866                p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_CLOSE;
2867                bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
2868            }
2869        }
2870        else if (bta_hl_find_an_active_mdl_idx(app_idx, mcl_idx,&mdl_idx))
2871        {
2872            p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_CLOSE;
2873            bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_EVT, p_data);
2874        }
2875        else
2876        {
2877            p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_NONE;
2878            bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_EVT, p_data);
2879        }
2880    }
2881}
2882
2883/*******************************************************************************
2884**
2885** Function         bta_hl_clean_app
2886**
2887** Description      Cleans up the HDP application resources and control block
2888**
2889** Returns          void
2890**
2891*******************************************************************************/
2892void bta_hl_clean_app(UINT8 app_idx)
2893{
2894    tBTA_HL_APP_CB         *p_acb   = BTA_HL_GET_APP_CB_PTR(app_idx);
2895    int i, num_act_apps=0;
2896
2897#if BTA_HL_DEBUG == TRUE
2898    APPL_TRACE_DEBUG("bta_hl_clean_app");
2899#endif
2900    MCA_Deregister((tMCA_HANDLE)p_acb->app_handle);
2901
2902    if (p_acb->sdp_handle) SDP_DeleteRecord(p_acb->sdp_handle);
2903
2904    memset((void *) p_acb, 0, sizeof(tBTA_HL_APP_CB));
2905
2906    /* check any application is still active */
2907    for (i=0; i < BTA_HL_NUM_APPS ; i ++)
2908    {
2909        p_acb = BTA_HL_GET_APP_CB_PTR(i);
2910        if (p_acb->in_use) num_act_apps++;
2911    }
2912
2913    if (!num_act_apps)
2914    {
2915        bta_sys_remove_uuid(UUID_SERVCLASS_HDP_PROFILE);
2916    }
2917}
2918
2919/*******************************************************************************
2920**
2921** Function      bta_hl_check_deregistration
2922**
2923** Description   This function checks whether there is a pending deregistration
2924**               request or not
2925**
2926** Returns      void
2927*******************************************************************************/
2928void bta_hl_check_deregistration(UINT8 app_idx, tBTA_HL_DATA *p_data )
2929{
2930    tBTA_HL_APP_CB      *p_acb  = BTA_HL_GET_APP_CB_PTR(app_idx);
2931    tBTA_HL_MCL_CB      *p_mcb;
2932    UINT8               mcl_idx;
2933    tBTA_HL             evt_data;
2934
2935#if (BTA_HL_DEBUG == TRUE)
2936    APPL_TRACE_DEBUG("bta_hl_check_deregistration");
2937#endif
2938
2939    if (p_acb->deregistering)
2940    {
2941        if (bta_hl_find_an_in_use_mcl_idx(app_idx, &mcl_idx))
2942        {
2943            p_mcb  = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2944            if (p_mcb->cch_oper != BTA_HL_CCH_OP_LOCAL_CLOSE)
2945            {
2946                if (p_mcb->cch_state == BTA_HL_CCH_OPENING_ST)
2947                    p_mcb->force_close_local_cch_opening = TRUE;
2948                p_mcb->cch_oper = BTA_HL_CCH_OP_LOCAL_CLOSE;
2949                APPL_TRACE_DEBUG("p_mcb->force_close_local_cch_opening=%d", p_mcb->force_close_local_cch_opening  );
2950                bta_hl_check_cch_close(app_idx,mcl_idx,p_data, TRUE);
2951            }
2952        }
2953        else
2954        {
2955            /* all cchs are closed */
2956            evt_data.dereg_cfm.app_handle = p_acb->app_handle;
2957            evt_data.dereg_cfm.app_id = p_data->api_dereg.app_id;
2958            evt_data.dereg_cfm.status = BTA_HL_STATUS_OK;
2959            p_acb->p_cback(BTA_HL_DEREGISTER_CFM_EVT, (tBTA_HL *) &evt_data );
2960            bta_hl_clean_app(app_idx);
2961            bta_hl_check_disable(p_data);
2962        }
2963    }
2964}
2965
2966
2967/*******************************************************************************
2968**
2969** Function      bta_hl_check_disable
2970**
2971** Description   This function checks whether there is a pending disable
2972**               request or not
2973**
2974** Returns      void
2975**
2976*******************************************************************************/
2977void bta_hl_check_disable(tBTA_HL_DATA *p_data )
2978{
2979    tBTA_HL_CB          *p_cb= &bta_hl_cb;
2980    tBTA_HL_APP_CB      *p_acb;
2981    UINT8               app_idx;
2982    tBTA_HL_CTRL        evt_data;
2983
2984#if (BTA_HL_DEBUG == TRUE)
2985    APPL_TRACE_DEBUG("bta_hl_check_disable");
2986#endif
2987
2988    if (bta_hl_cb.disabling)
2989    {
2990        if (bta_hl_find_an_in_use_app_idx(&app_idx))
2991        {
2992            p_acb  = BTA_HL_GET_APP_CB_PTR(app_idx);
2993            if (!p_acb->deregistering)
2994            {
2995                p_acb->deregistering = TRUE;
2996                bta_hl_check_deregistration(app_idx, p_data);
2997            }
2998        }
2999        else
3000        {
3001            /* all apps are deregistered */
3002            bta_sys_deregister(BTA_ID_HL);
3003            evt_data.disable_cfm.status = BTA_HL_STATUS_OK;
3004            if (p_cb->p_ctrl_cback) p_cb->p_ctrl_cback(BTA_HL_CTRL_DISABLE_CFM_EVT, (tBTA_HL_CTRL *) &evt_data);
3005            memset((void *) p_cb, 0, sizeof(tBTA_HL_CB));
3006        }
3007    }
3008}
3009
3010/*******************************************************************************
3011**
3012** Function      bta_hl_build_abort_cfm
3013**
3014** Description   This function builds the abort confirmation event data
3015**
3016** Returns      None
3017**
3018*******************************************************************************/
3019void  bta_hl_build_abort_cfm(tBTA_HL *p_evt_data,
3020                             tBTA_HL_APP_HANDLE app_handle,
3021                             tBTA_HL_MCL_HANDLE mcl_handle,
3022                             tBTA_HL_STATUS status)
3023{
3024    p_evt_data->dch_abort_cfm.status = status;
3025    p_evt_data->dch_abort_cfm.mcl_handle = mcl_handle;
3026    p_evt_data->dch_abort_cfm.app_handle = app_handle;
3027}
3028
3029/*******************************************************************************
3030**
3031** Function      bta_hl_build_abort_ind
3032**
3033** Description   This function builds the abort indication event data
3034**
3035** Returns      None
3036**
3037*******************************************************************************/
3038void  bta_hl_build_abort_ind(tBTA_HL *p_evt_data,
3039                             tBTA_HL_APP_HANDLE app_handle,
3040                             tBTA_HL_MCL_HANDLE mcl_handle)
3041{
3042    p_evt_data->dch_abort_ind.mcl_handle = mcl_handle;
3043    p_evt_data->dch_abort_ind.app_handle = app_handle;
3044}
3045/*******************************************************************************
3046**
3047** Function      bta_hl_build_close_cfm
3048**
3049** Description   This function builds the close confirmation event data
3050**
3051** Returns      None
3052**
3053*******************************************************************************/
3054void  bta_hl_build_dch_close_cfm(tBTA_HL *p_evt_data,
3055                                 tBTA_HL_APP_HANDLE app_handle,
3056                                 tBTA_HL_MCL_HANDLE mcl_handle,
3057                                 tBTA_HL_MDL_HANDLE mdl_handle,
3058                                 tBTA_HL_STATUS status)
3059{
3060    p_evt_data->dch_close_cfm.status = status;
3061    p_evt_data->dch_close_cfm.mdl_handle = mdl_handle;
3062    p_evt_data->dch_close_cfm.mcl_handle = mcl_handle;
3063    p_evt_data->dch_close_cfm.app_handle = app_handle;
3064}
3065
3066/*******************************************************************************
3067**
3068** Function      bta_hl_build_dch_close_ind
3069**
3070** Description   This function builds the close indication event data
3071**
3072** Returns      None
3073**
3074*******************************************************************************/
3075void  bta_hl_build_dch_close_ind(tBTA_HL *p_evt_data,
3076                                 tBTA_HL_APP_HANDLE app_handle,
3077                                 tBTA_HL_MCL_HANDLE mcl_handle,
3078                                 tBTA_HL_MDL_HANDLE mdl_handle,
3079                                 BOOLEAN intentional)
3080{
3081    p_evt_data->dch_close_ind.mdl_handle = mdl_handle;
3082    p_evt_data->dch_close_ind.mcl_handle = mcl_handle;
3083    p_evt_data->dch_close_ind.app_handle = app_handle;
3084    p_evt_data->dch_close_ind.intentional = intentional;
3085}
3086
3087/*******************************************************************************
3088**
3089** Function      bta_hl_build_send_data_cfm
3090**
3091** Description   This function builds the send data confirmation event data
3092**
3093** Returns      None
3094**
3095*******************************************************************************/
3096void  bta_hl_build_send_data_cfm(tBTA_HL *p_evt_data,
3097                                 tBTA_HL_APP_HANDLE app_handle,
3098                                 tBTA_HL_MCL_HANDLE mcl_handle,
3099                                 tBTA_HL_MDL_HANDLE mdl_handle,
3100                                 tBTA_HL_STATUS status )
3101{
3102
3103    p_evt_data->dch_send_data_cfm.mdl_handle = mdl_handle;
3104    p_evt_data->dch_send_data_cfm.mcl_handle = mcl_handle;
3105    p_evt_data->dch_send_data_cfm.app_handle = app_handle;
3106    p_evt_data->dch_send_data_cfm.status = status;
3107}
3108
3109/*******************************************************************************
3110**
3111** Function      bta_hl_build_rcv_data_ind
3112**
3113** Description   This function builds the received data indication event data
3114**
3115** Returns      None
3116**
3117*******************************************************************************/
3118void  bta_hl_build_rcv_data_ind(tBTA_HL *p_evt_data,
3119                                tBTA_HL_APP_HANDLE app_handle,
3120                                tBTA_HL_MCL_HANDLE mcl_handle,
3121                                tBTA_HL_MDL_HANDLE mdl_handle)
3122{
3123    p_evt_data->dch_rcv_data_ind.mdl_handle = mdl_handle;
3124    p_evt_data->dch_rcv_data_ind.mcl_handle = mcl_handle;
3125    p_evt_data->dch_rcv_data_ind.app_handle = app_handle;
3126}
3127
3128
3129/*******************************************************************************
3130**
3131** Function      bta_hl_build_cch_open_cfm
3132**
3133** Description   This function builds the CCH open confirmation event data
3134**
3135** Returns      None
3136**
3137*******************************************************************************/
3138void  bta_hl_build_cch_open_cfm(tBTA_HL *p_evt_data,
3139                                UINT8 app_id,
3140                                tBTA_HL_APP_HANDLE app_handle,
3141                                tBTA_HL_MCL_HANDLE mcl_handle,
3142                                BD_ADDR bd_addr,
3143                                tBTA_HL_STATUS status )
3144{
3145    p_evt_data->cch_open_cfm.app_id = app_id;
3146    p_evt_data->cch_open_cfm.app_handle = app_handle;
3147    p_evt_data->cch_open_cfm.mcl_handle = mcl_handle;
3148    bdcpy(p_evt_data->cch_open_cfm.bd_addr, bd_addr);
3149    p_evt_data->cch_open_cfm.status = status;
3150    APPL_TRACE_DEBUG("bta_hl_build_cch_open_cfm: status=%d",status);
3151}
3152
3153/*******************************************************************************
3154**
3155** Function      bta_hl_build_cch_open_ind
3156**
3157** Description   This function builds the CCH open indication event data
3158**
3159** Returns      None
3160**
3161*******************************************************************************/
3162void  bta_hl_build_cch_open_ind(tBTA_HL *p_evt_data, tBTA_HL_APP_HANDLE app_handle,
3163                                tBTA_HL_MCL_HANDLE mcl_handle,
3164                                BD_ADDR bd_addr )
3165{
3166
3167    p_evt_data->cch_open_ind.app_handle = app_handle;
3168    p_evt_data->cch_open_ind.mcl_handle = mcl_handle;
3169    bdcpy(p_evt_data->cch_open_ind.bd_addr, bd_addr);
3170}
3171
3172/*******************************************************************************
3173**
3174** Function      bta_hl_build_cch_close_cfm
3175**
3176** Description   This function builds the CCH close confirmation event data
3177**
3178** Returns      None
3179**
3180*******************************************************************************/
3181void  bta_hl_build_cch_close_cfm(tBTA_HL *p_evt_data,
3182                                 tBTA_HL_APP_HANDLE app_handle,
3183                                 tBTA_HL_MCL_HANDLE mcl_handle,
3184                                 tBTA_HL_STATUS status )
3185{
3186    p_evt_data->cch_close_cfm.mcl_handle = mcl_handle;
3187    p_evt_data->cch_close_cfm.app_handle = app_handle;
3188    p_evt_data->cch_close_cfm.status = status;
3189}
3190
3191
3192/*******************************************************************************
3193**
3194** Function      bta_hl_build_cch_close_ind
3195**
3196** Description   This function builds the CCH colse indication event data
3197**
3198** Returns      None
3199**
3200*******************************************************************************/
3201void  bta_hl_build_cch_close_ind(tBTA_HL *p_evt_data,
3202                                 tBTA_HL_APP_HANDLE app_handle,
3203                                 tBTA_HL_MCL_HANDLE mcl_handle,
3204                                 BOOLEAN intentional)
3205{
3206    p_evt_data->cch_close_ind.mcl_handle = mcl_handle;
3207    p_evt_data->cch_close_ind.app_handle = app_handle;
3208    p_evt_data->cch_close_ind.intentional = intentional;
3209}
3210
3211/*******************************************************************************
3212**
3213** Function      bta_hl_build_dch_open_cfm
3214**
3215** Description   This function builds the DCH open confirmation event data
3216**
3217** Returns      None
3218**
3219*******************************************************************************/
3220void  bta_hl_build_dch_open_cfm(tBTA_HL *p_evt_data,
3221                                tBTA_HL_APP_HANDLE app_handle,
3222                                tBTA_HL_MCL_HANDLE mcl_handle,
3223                                tBTA_HL_MDL_HANDLE mdl_handle,
3224                                tBTA_HL_MDEP_ID local_mdep_id,
3225                                tBTA_HL_MDL_ID mdl_id,
3226                                tBTA_HL_DCH_MODE dch_mode,
3227                                BOOLEAN first_reliable,
3228                                UINT16 mtu,
3229                                tBTA_HL_STATUS status)
3230
3231{
3232    p_evt_data->dch_open_cfm.mdl_handle = mdl_handle;
3233    p_evt_data->dch_open_cfm.mcl_handle = mcl_handle;
3234    p_evt_data->dch_open_cfm.app_handle = app_handle;
3235    p_evt_data->dch_open_cfm.local_mdep_id = local_mdep_id;
3236    p_evt_data->dch_open_cfm.mdl_id = mdl_id;
3237    p_evt_data->dch_open_cfm.dch_mode = dch_mode;
3238    p_evt_data->dch_open_cfm.first_reliable = first_reliable;
3239    p_evt_data->dch_open_cfm.mtu = mtu;
3240    p_evt_data->dch_open_cfm.status = status;
3241}
3242
3243
3244/*******************************************************************************
3245**
3246** Function      bta_hl_build_sdp_query_cfm
3247**
3248** Description   This function builds the SDP query indication event data
3249**
3250** Returns      None
3251**
3252*******************************************************************************/
3253void  bta_hl_build_sdp_query_cfm(tBTA_HL *p_evt_data,
3254                                 UINT8 app_id,
3255                                 tBTA_HL_APP_HANDLE app_handle,
3256                                 BD_ADDR bd_addr,
3257                                 tBTA_HL_SDP *p_sdp,
3258                                 tBTA_HL_STATUS status)
3259
3260{
3261    APPL_TRACE_DEBUG("bta_hl_build_sdp_query_cfm: app_id = %d, app_handle=%d",
3262                        app_id,app_handle);
3263    p_evt_data->sdp_query_cfm.app_id = app_id;
3264    p_evt_data->sdp_query_cfm.app_handle = app_handle;
3265    bdcpy(p_evt_data->sdp_query_cfm.bd_addr, bd_addr);
3266    p_evt_data->sdp_query_cfm.p_sdp = p_sdp;
3267    p_evt_data->sdp_query_cfm.status = status;
3268}
3269
3270
3271/*******************************************************************************
3272**
3273** Function      bta_hl_build_delete_mdl_cfm
3274**
3275** Description   This function builds the delete MDL confirmation event data
3276**
3277** Returns      None
3278**
3279*******************************************************************************/
3280void  bta_hl_build_delete_mdl_cfm(tBTA_HL *p_evt_data,
3281                                  tBTA_HL_APP_HANDLE app_handle,
3282                                  tBTA_HL_MCL_HANDLE mcl_handle,
3283                                  tBTA_HL_MDL_ID mdl_id,
3284                                  tBTA_HL_STATUS status)
3285
3286{
3287    p_evt_data->delete_mdl_cfm.mcl_handle = mcl_handle;
3288    p_evt_data->delete_mdl_cfm.app_handle = app_handle;
3289    p_evt_data->delete_mdl_cfm.mdl_id = mdl_id;
3290    p_evt_data->delete_mdl_cfm.status = status;
3291}
3292
3293/*******************************************************************************
3294**
3295** Function      bta_hl_build_echo_test_cfm
3296**
3297** Description   This function builds the echo test confirmation event data
3298**
3299** Returns      None
3300**
3301*******************************************************************************/
3302void  bta_hl_build_echo_test_cfm(tBTA_HL *p_evt_data,
3303                                 tBTA_HL_APP_HANDLE app_handle,
3304                                 tBTA_HL_MCL_HANDLE mcl_handle,
3305                                 tBTA_HL_STATUS status )
3306{
3307    p_evt_data->echo_test_cfm.mcl_handle = mcl_handle;
3308    p_evt_data->echo_test_cfm.app_handle = app_handle;
3309    p_evt_data->echo_test_cfm.status = status;
3310}
3311
3312
3313/*****************************************************************************
3314**  Debug Functions
3315*****************************************************************************/
3316#if (BTA_HL_DEBUG == TRUE)
3317
3318/*******************************************************************************
3319**
3320** Function         bta_hl_status_code
3321**
3322** Description      get the status string pointer
3323**
3324** Returns          char * - status string pointer
3325**
3326*******************************************************************************/
3327char *bta_hl_status_code(tBTA_HL_STATUS status)
3328{
3329    switch (status)
3330    {
3331        case BTA_HL_STATUS_OK:
3332            return "BTA_HL_STATUS_OK";
3333        case BTA_HL_STATUS_FAIL:
3334            return "BTA_HL_STATUS_FAIL";
3335        case BTA_HL_STATUS_ABORTED:
3336            return "BTA_HL_STATUS_ABORTED";
3337        case BTA_HL_STATUS_NO_RESOURCE:
3338            return "BTA_HL_STATUS_NO_RESOURCE";
3339        case BTA_HL_STATUS_LAST_ITEM:
3340            return "BTA_HL_STATUS_LAST_ITEM";
3341        case BTA_HL_STATUS_DUPLICATE_APP_ID:
3342            return "BTA_HL_STATUS_DUPLICATE_APP_ID";
3343        case BTA_HL_STATUS_INVALID_APP_HANDLE:
3344            return "BTA_HL_STATUS_INVALID_APP_HANDLE";
3345        case BTA_HL_STATUS_INVALID_MCL_HANDLE:
3346            return "BTA_HL_STATUS_INVALID_MCL_HANDLE";
3347        case BTA_HL_STATUS_MCAP_REG_FAIL:
3348            return "BTA_HL_STATUS_MCAP_REG_FAIL";
3349        case BTA_HL_STATUS_MDEP_CO_FAIL:
3350            return "BTA_HL_STATUS_MDEP_CO_FAIL";
3351        case BTA_HL_STATUS_ECHO_CO_FAIL:
3352            return "BTA_HL_STATUS_ECHO_CO_FAIL";
3353        case BTA_HL_STATUS_MDL_CFG_CO_FAIL:
3354            return "BTA_HL_STATUS_MDL_CFG_CO_FAIL";
3355        case BTA_HL_STATUS_SDP_NO_RESOURCE:
3356            return "BTA_HL_STATUS_SDP_NO_RESOURCE";
3357        case BTA_HL_STATUS_SDP_FAIL:
3358            return "BTA_HL_STATUS_SDP_FAIL";
3359        case BTA_HL_STATUS_NO_CCH:
3360            return "BTA_HL_STATUS_NO_CCH";
3361        case BTA_HL_STATUS_NO_MCL:
3362            return "BTA_HL_STATUS_NO_MCL";
3363
3364        case BTA_HL_STATUS_NO_FIRST_RELIABLE:
3365            return "BTA_HL_STATUS_NO_FIRST_RELIABLE";
3366        case BTA_HL_STATUS_INVALID_DCH_CFG:
3367            return "BTA_HL_STATUS_INVALID_DCH_CFG";
3368        case BTA_HL_STATUS_INVALID_BD_ADDR:
3369            return "BTA_HL_STATUS_INVALID_BD_ADDR";
3370        case BTA_HL_STATUS_INVALID_RECONNECT_CFG:
3371            return "BTA_HL_STATUS_INVALID_RECONNECT_CFG";
3372        case BTA_HL_STATUS_ECHO_TEST_BUSY:
3373            return "BTA_HL_STATUS_ECHO_TEST_BUSY";
3374        case BTA_HL_STATUS_INVALID_LOCAL_MDEP_ID:
3375            return "BTA_HL_STATUS_INVALID_LOCAL_MDEP_ID";
3376        case BTA_HL_STATUS_INVALID_MDL_ID:
3377            return "BTA_HL_STATUS_INVALID_MDL_ID";
3378        case BTA_HL_STATUS_NO_MDL_ID_FOUND:
3379            return "BTA_HL_STATUS_NO_MDL_ID_FOUND";
3380        case BTA_HL_STATUS_DCH_BUSY:
3381            return "BTA_HL_STATUS_DCH_BUSY";
3382        default:
3383            return "Unknown status code";
3384    }
3385}
3386/*******************************************************************************
3387**
3388** Function         bta_hl_evt_code
3389**
3390** Description      Maps HL event code to the corresponding event string
3391**
3392** Returns          string pointer for the associated event name
3393**
3394*******************************************************************************/
3395char *bta_hl_evt_code(tBTA_HL_INT_EVT evt_code)
3396{
3397    switch (evt_code)
3398    {
3399        case BTA_HL_CCH_OPEN_EVT:
3400            return "BTA_HL_CCH_OPEN_EVT";
3401        case BTA_HL_CCH_SDP_OK_EVT:
3402            return "BTA_HL_CCH_SDP_OK_EVT";
3403        case BTA_HL_CCH_SDP_FAIL_EVT:
3404            return "BTA_HL_CCH_SDP_FAIL_EVT";
3405        case BTA_HL_MCA_CONNECT_IND_EVT:
3406            return "BTA_HL_MCA_CONNECT_IND_EVT";
3407        case BTA_HL_MCA_DISCONNECT_IND_EVT:
3408            return "BTA_HL_MCA_DISCONNECT_IND_EVT";
3409
3410        case BTA_HL_CCH_CLOSE_EVT:
3411            return "BTA_HL_CCH_CLOSE_EVT";
3412        case BTA_HL_CCH_CLOSE_CMPL_EVT:
3413            return "BTA_HL_CCH_CLOSE_CMPL_EVT";
3414        case BTA_HL_DCH_OPEN_EVT:
3415            return "BTA_HL_DCH_OPEN_EVT";
3416        case BTA_HL_MCA_CREATE_IND_EVT:
3417            return "BTA_HL_MCA_CREATE_IND_EVT";
3418        case BTA_HL_MCA_CREATE_CFM_EVT:
3419            return "BTA_HL_MCA_CREATE_CFM_EVT";
3420        case BTA_HL_MCA_OPEN_IND_EVT:
3421            return "BTA_HL_MCA_OPEN_IND_EVT";
3422        case BTA_HL_MCA_OPEN_CFM_EVT:
3423            return "BTA_HL_MCA_OPEN_CFM_EVT";
3424        case BTA_HL_DCH_CLOSE_EVT:
3425            return "BTA_HL_DCH_CLOSE_EVT";
3426        case BTA_HL_MCA_CLOSE_IND_EVT:
3427            return "BTA_HL_MCA_CLOSE_IND_EVT";
3428        case BTA_HL_MCA_CLOSE_CFM_EVT:
3429            return "BTA_HL_MCA_CLOSE_CFM_EVT";
3430        case BTA_HL_API_SEND_DATA_EVT:
3431            return "BTA_HL_API_SEND_DATA_EVT";
3432        case BTA_HL_MCA_RCV_DATA_EVT:
3433            return "BTA_HL_MCA_RCV_DATA_EVT";
3434        case BTA_HL_DCH_CLOSE_CMPL_EVT:
3435            return "BTA_HL_DCH_CLOSE_CMPL_EVT";
3436
3437        case BTA_HL_API_ENABLE_EVT:
3438            return "BTA_HL_API_ENABLE_EVT";
3439        case BTA_HL_API_DISABLE_EVT:
3440            return "BTA_HL_API_DISABLE_EVT";
3441        case BTA_HL_API_UPDATE_EVT:
3442             return "BTA_HL_API_UPDATE_EVT";
3443        case BTA_HL_API_REGISTER_EVT:
3444            return "BTA_HL_API_REGISTER_EVT";
3445        case BTA_HL_API_DEREGISTER_EVT:
3446            return "BTA_HL_API_DEREGISTER_EVT";
3447
3448        case BTA_HL_API_CCH_OPEN_EVT:
3449            return "BTA_HL_API_CCH_OPEN_EVT";
3450
3451        case BTA_HL_API_CCH_CLOSE_EVT:
3452            return "BTA_HL_API_CCH_CLOSE_EVT";
3453        case BTA_HL_API_DCH_OPEN_EVT:
3454            return "BTA_HL_API_DCH_OPEN_EVT";
3455
3456        case BTA_HL_API_DCH_RECONNECT_EVT:
3457            return "BTA_HL_API_DCH_RECONNECT_EVT";
3458        case BTA_HL_API_DCH_CLOSE_EVT:
3459            return "BTA_HL_API_DCH_CLOSE_EVT";
3460        case BTA_HL_API_DELETE_MDL_EVT:
3461            return "BTA_HL_API_DELETE_MDL_EVT";
3462        case BTA_HL_API_DCH_ABORT_EVT:
3463            return "BTA_HL_API_DCH_ABORT_EVT";
3464
3465        case BTA_HL_DCH_RECONNECT_EVT:
3466            return "BTA_HL_DCH_RECONNECT_EVT";
3467        case BTA_HL_DCH_SDP_INIT_EVT:
3468            return "BTA_HL_DCH_SDP_INIT_EVT";
3469        case BTA_HL_DCH_SDP_FAIL_EVT:
3470            return "BTA_HL_DCH_SDP_FAIL_EVT";
3471        case BTA_HL_API_DCH_ECHO_TEST_EVT:
3472            return "BTA_HL_API_DCH_ECHO_TEST_EVT";
3473        case BTA_HL_DCH_CLOSE_ECHO_TEST_EVT:
3474            return "BTA_HL_DCH_CLOSE_ECHO_TEST_EVT";
3475        case BTA_HL_MCA_RECONNECT_IND_EVT:
3476            return "BTA_HL_MCA_RECONNECT_IND_EVT";
3477        case BTA_HL_MCA_RECONNECT_CFM_EVT:
3478            return "BTA_HL_MCA_RECONNECT_CFM_EVT";
3479        case BTA_HL_API_DCH_CREATE_RSP_EVT:
3480            return "BTA_HL_API_DCH_CREATE_RSP_EVT";
3481        case BTA_HL_DCH_ABORT_EVT:
3482            return "BTA_HL_DCH_ABORT_EVT";
3483        case BTA_HL_MCA_ABORT_IND_EVT:
3484            return "BTA_HL_MCA_ABORT_IND_EVT";
3485        case BTA_HL_MCA_ABORT_CFM_EVT:
3486            return "BTA_HL_MCA_ABORT_CFM_EVT";
3487        case BTA_HL_MCA_DELETE_IND_EVT:
3488            return "BTA_HL_MCA_DELETE_IND_EVT";
3489        case BTA_HL_MCA_DELETE_CFM_EVT:
3490            return "BTA_HL_MCA_DELETE_CFM_EVT";
3491        case BTA_HL_MCA_CONG_CHG_EVT:
3492            return "BTA_HL_MCA_CONG_CHG_EVT";
3493        case BTA_HL_CI_GET_TX_DATA_EVT:
3494            return "BTA_HL_CI_GET_TX_DATA_EVT";
3495        case BTA_HL_CI_PUT_RX_DATA_EVT:
3496            return "BTA_HL_CI_PUT_RX_DATA_EVT";
3497        case BTA_HL_CI_GET_ECHO_DATA_EVT:
3498            return "BTA_HL_CI_GET_ECHO_DATA_EVT";
3499        case BTA_HL_DCH_ECHO_TEST_EVT:
3500            return "BTA_HL_DCH_ECHO_TEST_EVT";
3501        case BTA_HL_CI_PUT_ECHO_DATA_EVT:
3502            return "BTA_HL_CI_PUT_ECHO_DATA_EVT";
3503        case BTA_HL_API_SDP_QUERY_EVT:
3504            return "BTA_HL_API_SDP_QUERY_EVT";
3505        case BTA_HL_SDP_QUERY_OK_EVT:
3506            return "BTA_HL_SDP_QUERY_OK_EVT";
3507        case BTA_HL_SDP_QUERY_FAIL_EVT:
3508            return "BTA_HL_SDP_QUERY_FAIL_EVT";
3509        case BTA_HL_MCA_RSP_TOUT_IND_EVT:
3510            return "BTA_HL_MCA_RSP_TOUT_IND_EVT";
3511
3512        default:
3513            return "Unknown HL event code";
3514    }
3515}
3516
3517#endif  /* Debug Functions */
3518#endif // HL_INCLUDED
3519
3520
3521
3522
3523
3524
3525
3526
3527