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