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