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