OSDN Git Service

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