1/******************************************************************************
2 *
3 *  Copyright (C) 2009-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 *  Filename:      btif_hl.c
22 *
23 *  Description:   Health Device Profile Bluetooth Interface
24 *
25 *
26 ***********************************************************************************/
27#define LOG_TAG "BTIF_HL"
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <errno.h>
32#include <string.h>
33#include <sys/types.h>
34#include <sys/socket.h>
35#include <sys/un.h>
36#include <time.h>
37#include <fcntl.h>
38#include <unistd.h>
39#include <pthread.h>
40#include <signal.h>
41#include <ctype.h>
42#include <sys/select.h>
43#include <sys/poll.h>
44#include <cutils/sockets.h>
45#include <cutils/log.h>
46
47#include <hardware/bluetooth.h>
48#include <hardware/bt_hl.h>
49
50#include "btif_common.h"
51#include "btif_util.h"
52#include "gki.h"
53#include "bd.h"
54#include "bta_api.h"
55#include "bta_hl_api.h"
56#include "mca_api.h"
57#include "btif_hl.h"
58#include "btif_storage.h"
59#include "btu.h"
60
61#define MAX_DATATYPE_SUPPORTED 8
62
63extern int btif_hl_update_maxfd( int max_org_s);
64extern void btif_hl_select_monitor_callback( fd_set *p_cur_set, fd_set *p_org_set );
65extern void btif_hl_select_wakeup_callback( fd_set *p_org_set , int wakeup_signal );
66extern int btif_hl_update_maxfd( int max_org_s);
67extern void btif_hl_select_monitor_callback( fd_set *p_cur_set, fd_set *p_org_set );
68extern void btif_hl_select_wakeup_callback( fd_set *p_org_set , int wakeup_signal );
69extern void btif_hl_soc_thread_init(void);
70extern void btif_hl_release_mcl_sockets(UINT8 app_idx, UINT8 mcl_idx);
71extern BOOLEAN btif_hl_create_socket(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx);
72extern void btif_hl_release_socket(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx);
73
74btif_hl_cb_t btif_hl_cb;
75btif_hl_cb_t *p_btif_hl_cb = &btif_hl_cb;
76
77/************************************************************************************
78**  Static variables
79************************************************************************************/
80static bthl_callbacks_t  bt_hl_callbacks_cb;
81static bthl_callbacks_t *bt_hl_callbacks=NULL;
82
83/* signal socketpair to wake up select loop */
84
85const int btif_hl_signal_select_wakeup = 1;
86const int btif_hl_signal_select_exit = 2;
87const int btif_hl_signal_select_close_connected = 3;
88
89static int listen_s = -1;
90static int connected_s = -1;
91static int select_thread_id = -1;
92static int signal_fds[2];
93static BUFFER_Q soc_queue;
94static int reg_counter;
95
96static inline int btif_hl_select_wakeup(void);
97static inline int btif_hl_select_exit(void);
98static inline int btif_hl_select_close_connected(void);
99static inline int btif_hl_close_select_thread(void);
100static UINT8 btif_hl_get_next_app_id(void);
101static int btif_hl_get_next_channel_id(UINT8 app_id);
102static void btif_hl_init_next_app_id(void);
103static void btif_hl_init_next_channel_id(void);
104static void btif_hl_ctrl_cback(tBTA_HL_CTRL_EVT event, tBTA_HL_CTRL *p_data);
105static void btif_hl_set_state(btif_hl_state_t state);
106static btif_hl_state_t btif_hl_get_state(void);
107static void btif_hl_cback(tBTA_HL_EVT event, tBTA_HL *p_data);
108static void btif_hl_proc_cb_evt(UINT16 event, char* p_param);
109
110#define CHECK_CALL_CBACK(P_CB, P_CBACK, ...)\
111    if (P_CB && P_CB->P_CBACK) {            \
112        P_CB->P_CBACK(__VA_ARGS__);         \
113    }                                       \
114    else {                                  \
115        ASSERTC(0, "Callback is NULL", 0);  \
116    }
117
118
119#define BTIF_HL_CALL_CBACK(P_CB, P_CBACK, ...)\
120     if((p_btif_hl_cb->state != BTIF_HL_STATE_DISABLING) &&\
121         (p_btif_hl_cb->state != BTIF_HL_STATE_DISABLED))  \
122     {                                                     \
123        if (P_CB && P_CB->P_CBACK) {                       \
124            P_CB->P_CBACK(__VA_ARGS__);                    \
125        }                                                  \
126        else {                                             \
127            ASSERTC(0, "Callback is NULL", 0);             \
128        }                                                  \
129    }
130
131
132#define CHECK_BTHL_INIT() if (bt_hl_callbacks == NULL)\
133    {\
134        BTIF_TRACE_WARNING1("BTHL: %s: BTHL not initialized", __FUNCTION__);\
135        return BT_STATUS_NOT_READY;\
136    }\
137    else\
138    {\
139        BTIF_TRACE_EVENT1("BTHL: %s", __FUNCTION__);\
140    }
141
142
143static const btif_hl_data_type_cfg_t data_type_table[] = {
144    /* Data Specilization                   Ntx     Nrx (from Bluetooth SIG's HDP whitepaper)*/
145    {BTIF_HL_DATA_TYPE_PULSE_OXIMETER,      9216,   256},
146    {BTIF_HL_DATA_TYPE_BLOOD_PRESSURE_MON,  896,    224},
147    {BTIF_HL_DATA_TYPE_BODY_THERMOMETER,    896,    224},
148    {BTIF_HL_DATA_TYPE_BODY_WEIGHT_SCALE,   896,    224},
149    {BTIF_HL_DATA_TYPE_GLUCOSE_METER,       896,    224},
150    {BTIF_HL_DATA_TYPE_STEP_COUNTER,        6624,   224},
151    {BTIF_HL_DATA_TYPE_BCA,                 7730,   1230},
152    {BTIF_HL_DATA_TYPE_PEAK_FLOW    ,       2030,   224},
153    {BTIF_HL_DATA_TYPE_ACTIVITY_HUB,        5120,   224},
154    {BTIF_HL_DATA_TYPE_AMM,                 1024,   64}
155};
156
157#define BTIF_HL_DATA_TABLE_SIZE  (sizeof(data_type_table) / sizeof(btif_hl_data_type_cfg_t))
158#define BTIF_HL_DEFAULT_SRC_TX_APDU_SIZE   10240 /* use this size if the data type is not
159                                                    defined in the table; for future proof */
160#define BTIF_HL_DEFAULT_SRC_RX_APDU_SIZE   512  /* use this size if the data type is not
161                                                   defined in the table; for future proof */
162
163#define BTIF_HL_ECHO_MAX_TX_RX_APDU_SIZE 1024
164
165/************************************************************************************
166**  Static utility functions
167************************************************************************************/
168
169#define BTIF_IF_GET_NAME 16
170void btif_hl_display_calling_process_name(void)
171{
172    char name[16];
173    prctl(BTIF_IF_GET_NAME, name, 0, 0, 0);
174    BTIF_TRACE_DEBUG1("Process name (%s)", name);
175}
176#define BTIF_TIMEOUT_CCH_NO_DCH_SECS   30
177/*******************************************************************************
178**
179** Function      btif_hl_if_channel_setup_pending
180**
181** Description   check whether channel id is in setup pending state or not
182**
183** Returns      BOOLEAN
184**
185*******************************************************************************/
186BOOLEAN btif_hl_if_channel_setup_pending(int channel_id, UINT8 *p_app_idx, UINT8 *p_mcl_idx)
187{
188    btif_hl_app_cb_t    *p_acb;
189    btif_hl_mcl_cb_t    *p_mcb;
190    UINT8 i, j;
191    BOOLEAN found=FALSE;
192    for (i=0; i < BTA_HL_NUM_APPS ; i ++)
193    {
194        p_acb  =BTIF_HL_GET_APP_CB_PTR(i);
195        if (p_acb->in_use)
196        {
197            for (j=0; j< BTA_HL_NUM_MCLS; j++)
198            {
199                p_mcb = BTIF_HL_GET_MCL_CB_PTR(i, j);
200                if (p_mcb->in_use &&
201                    p_mcb->is_connected && p_mcb->pcb.channel_id == channel_id )
202                {
203                    found = TRUE;
204                    *p_app_idx = i;
205                    *p_mcl_idx = j;
206                    break;
207                }
208            }
209        }
210        if (found)
211            break;
212    }
213    BTIF_TRACE_DEBUG5("%s found=%d channel_id=0x%08x",
214                      __FUNCTION__, found, channel_id, *p_app_idx, *p_mcl_idx);
215    return found;
216
217}
218/*******************************************************************************
219**
220** Function      btif_hl_num_dchs_in_use
221**
222** Description find number of DCHs in use
223**
224** Returns      UINT8
225*******************************************************************************/
226UINT8 btif_hl_num_dchs_in_use(UINT8 mcl_handle){
227
228    btif_hl_app_cb_t    * p_acb;
229    btif_hl_mcl_cb_t    *p_mcb;
230    UINT8               i,j,x;
231    UINT8               cnt=0;
232
233    for (i=0; i<BTA_HL_NUM_APPS; i++)
234    {
235        BTIF_TRACE_DEBUG1("btif_hl_num_dchs:i = %d",i);
236        p_acb =BTIF_HL_GET_APP_CB_PTR(i);
237        if (p_acb && p_acb->in_use)
238        {
239            for (j=0; j < BTA_HL_NUM_MCLS ; j++)
240            {
241                if(p_acb->mcb[j].in_use)
242                    BTIF_TRACE_DEBUG3("btif_hl_num_dchs:mcb in use j=%d, mcl_handle=%d,mcb handle=%d",
243                                        j,mcl_handle, p_acb->mcb[j].mcl_handle);
244                if (p_acb->mcb[j].in_use &&
245                    (p_acb->mcb[j].mcl_handle == mcl_handle))
246                {
247                    p_mcb = &p_acb->mcb[j];
248                    BTIF_TRACE_DEBUG1("btif_hl_num_dchs: mcl handle found j =%d",j);
249                    for (x=0; x < BTA_HL_NUM_MDLS_PER_MCL ; x ++)
250                    {
251                        if (p_mcb->mdl[x].in_use)
252                        {
253                            BTIF_TRACE_DEBUG1("btif_hl_num_dchs_in_use:found x =%d",x);
254                            cnt++;
255                        }
256                    }
257                }
258            }
259        }
260    }
261
262    BTIF_TRACE_DEBUG2("%s dch in use count=%d", __FUNCTION__, cnt);
263    return cnt;
264}
265/*******************************************************************************
266**
267** Function      btif_hl_tmr_hdlr
268**
269** Description   Process timer timeout
270**
271** Returns      void
272*******************************************************************************/
273void btif_hl_tmr_hdlr(TIMER_LIST_ENT *tle)
274{
275    btif_hl_mcl_cb_t    *p_mcb;
276    UINT8               i,j;
277    BTIF_TRACE_DEBUG2("%s timer_in_use=%d",  __FUNCTION__, tle->in_use );
278
279    for (i=0; i < BTA_HL_NUM_APPS ; i ++)
280    {
281        for (j=0; j< BTA_HL_NUM_MCLS; j++)
282        {
283            p_mcb =BTIF_HL_GET_MCL_CB_PTR(i,j);
284
285            if (p_mcb->cch_timer_active)
286            {
287                BTIF_TRACE_DEBUG3("%app_idx=%d, mcl_idx=%d mcl-connected=%d",
288                                  i, j,  p_mcb->is_connected);
289                p_mcb->cch_timer_active = FALSE;
290                if (p_mcb->is_connected)
291                {
292                    BTIF_TRACE_DEBUG3("Idle timeout Close CCH app_idx=%d mcl_idx=%d mcl_handle=%d",
293                                      i ,j, p_mcb->mcl_handle);
294                    BTA_HlCchClose(p_mcb->mcl_handle);
295                }
296                else
297                {
298                    BTIF_TRACE_DEBUG2("CCH idle timeout But CCH not connected app_idx=%d mcl_idx=%d ",i,j);
299                }
300            }
301        }
302    }
303}
304/*******************************************************************************
305**
306** Function      btif_hl_stop_cch_timer
307**
308** Description  stop CCH timer
309**
310** Returns      void
311*******************************************************************************/
312void btif_hl_stop_cch_timer(UINT8 app_idx, UINT8 mcl_idx)
313{
314    btif_hl_mcl_cb_t    *p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
315    BTIF_TRACE_DEBUG4("%s app_idx=%d, mcl_idx=%d timer_in_use=%d",
316                      __FUNCTION__,app_idx, mcl_idx, p_mcb->cch_timer.in_use);
317
318    p_mcb->cch_timer_active = FALSE;
319    if (p_mcb->cch_timer.in_use)
320    {
321        BTIF_TRACE_DEBUG0("stop CCH timer ");
322        btu_stop_timer(&p_mcb->cch_timer);
323    }
324}
325/*******************************************************************************
326**
327** Function      btif_hl_start_cch_timer
328**
329** Description  start CCH timer
330**
331** Returns      void
332*******************************************************************************/
333void btif_hl_start_cch_timer(UINT8 app_idx, UINT8 mcl_idx)
334{
335    btif_hl_mcl_cb_t    *p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
336    BTIF_TRACE_DEBUG5("%s app_idx=%d, mcl_idx=%d  timer_active=%d timer_in_use=%d",
337                      __FUNCTION__,app_idx, mcl_idx,
338                      p_mcb->cch_timer_active, p_mcb->cch_timer.in_use);
339
340    p_mcb->cch_timer_active = TRUE;
341    if (!p_mcb->cch_timer.in_use)
342    {
343        BTIF_TRACE_DEBUG0("Start CCH timer ");
344        memset(&p_mcb->cch_timer, 0, sizeof(TIMER_LIST_ENT));
345        p_mcb->cch_timer.param = (UINT32)btif_hl_tmr_hdlr;
346        btu_start_timer(&p_mcb->cch_timer, BTU_TTYPE_USER_FUNC,
347                        BTIF_TIMEOUT_CCH_NO_DCH_SECS);
348    }
349    else
350    {
351        BTIF_TRACE_DEBUG0("Restart CCH timer ");
352        btu_stop_timer(&p_mcb->cch_timer);
353        btu_start_timer(&p_mcb->cch_timer, BTU_TTYPE_USER_FUNC,
354                        BTIF_TIMEOUT_CCH_NO_DCH_SECS);
355    }
356
357}
358/*******************************************************************************
359**
360** Function      btif_hl_find_mdl_idx
361**
362** Description  Find the MDL index using MDL ID
363**
364** Returns      BOOLEAN
365**
366*******************************************************************************/
367static BOOLEAN btif_hl_find_mdl_idx(UINT8 app_idx, UINT8 mcl_idx, UINT16 mdl_id,
368                                    UINT8 *p_mdl_idx)
369{
370    btif_hl_mcl_cb_t      *p_mcb  = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
371    BOOLEAN found=FALSE;
372    UINT8 i;
373
374    for (i=0; i < BTA_HL_NUM_MDLS_PER_MCL ; i ++)
375    {
376        if (p_mcb->mdl[i].in_use  &&
377            (mdl_id !=0) &&
378            (p_mcb->mdl[i].mdl_id== mdl_id))
379        {
380            found = TRUE;
381            *p_mdl_idx = i;
382            break;
383        }
384    }
385
386    BTIF_TRACE_DEBUG4("%s found=%d mdl_id=%d mdl_idx=%d ",
387                      __FUNCTION__,found, mdl_id, i);
388
389    return found;
390}
391
392/*******************************************************************************
393**
394** Function      btif_hl_get_buf
395**
396** Description   get buffer
397**
398** Returns     void
399**
400*******************************************************************************/
401void * btif_hl_get_buf(UINT16 size)
402{
403    void *p_new;
404
405    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
406    BTIF_TRACE_DEBUG2("ret size=%d GKI_MAX_BUF_SIZE=%d",size, 6000);
407
408    if (size < 6000)
409    {
410        p_new = GKI_getbuf(size);
411    }
412    else
413    {
414        BTIF_TRACE_DEBUG0("btif_hl_get_buf use HL large data pool");
415        p_new = GKI_getpoolbuf(4);
416    }
417
418    return p_new;
419}
420/*******************************************************************************
421**
422** Function      btif_hl_free_buf
423**
424** Description free buffer
425**
426** Return void
427**
428*******************************************************************************/
429void btif_hl_free_buf(void **p)
430{
431    if (*p != NULL)
432    {
433        BTIF_TRACE_DEBUG1("%s OK", __FUNCTION__ );
434        GKI_freebuf(*p);
435        *p = NULL;
436    }
437    else
438        BTIF_TRACE_ERROR1("%s NULL pointer",__FUNCTION__ );
439}
440/*******************************************************************************
441**
442** Function      btif_hl_is_the_first_reliable_existed
443**
444** Description  This function checks whether the first reliable DCH channel
445**              has been setup on the MCL or not
446**
447** Returns      BOOLEAN - TRUE exist
448**                        FALSE does not exist
449**
450*******************************************************************************/
451BOOLEAN btif_hl_is_the_first_reliable_existed(UINT8 app_idx, UINT8 mcl_idx )
452{
453    btif_hl_mcl_cb_t          *p_mcb  =BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
454    BOOLEAN is_existed =FALSE;
455    UINT8 i ;
456
457    for (i=0; i< BTA_HL_NUM_MDLS_PER_MCL; i++)
458    {
459        if (p_mcb->mdl[i].in_use && p_mcb->mdl[i].is_the_first_reliable)
460        {
461            is_existed = TRUE;
462            break;
463        }
464    }
465
466    BTIF_TRACE_DEBUG1("bta_hl_is_the_first_reliable_existed is_existed=%d  ",is_existed );
467    return is_existed;
468}
469/*******************************************************************************
470**
471** Function      btif_hl_clean_delete_mdl
472**
473** Description   Cleanup the delete mdl control block
474**
475** Returns     Nothing
476**
477*******************************************************************************/
478static void btif_hl_clean_delete_mdl(btif_hl_delete_mdl_t *p_cb)
479{
480    BTIF_TRACE_DEBUG1("%s", __FUNCTION__ );
481    memset(p_cb, 0 , sizeof(btif_hl_delete_mdl_t));
482}
483
484/*******************************************************************************
485**
486** Function      btif_hl_clean_pcb
487**
488** Description   Cleanup the pending chan control block
489**
490** Returns     Nothing
491**
492*******************************************************************************/
493static void btif_hl_clean_pcb(btif_hl_pending_chan_cb_t *p_pcb)
494{
495    BTIF_TRACE_DEBUG1("%s", __FUNCTION__ );
496    memset(p_pcb, 0 , sizeof(btif_hl_pending_chan_cb_t));
497}
498
499
500/*******************************************************************************
501**
502** Function      btif_hl_clean_mdl_cb
503**
504** Description   Cleanup the MDL control block
505**
506** Returns     Nothing
507**
508*******************************************************************************/
509static void btif_hl_clean_mdl_cb(btif_hl_mdl_cb_t *p_dcb)
510{
511    BTIF_TRACE_DEBUG1("%s", __FUNCTION__ );
512    btif_hl_free_buf((void **) &p_dcb->p_rx_pkt);
513    btif_hl_free_buf((void **) &p_dcb->p_tx_pkt);
514    memset(p_dcb, 0 , sizeof(btif_hl_mdl_cb_t));
515}
516
517
518/*******************************************************************************
519**
520** Function      btif_hl_reset_mcb
521**
522** Description   Reset MCL control block
523**
524** Returns      BOOLEAN
525**
526*******************************************************************************/
527static void btif_hl_clean_mcl_cb(UINT8 app_idx, UINT8 mcl_idx)
528{
529    btif_hl_mcl_cb_t     *p_mcb;
530    BTIF_TRACE_DEBUG3("%s app_idx=%d, mcl_idx=%d", __FUNCTION__,app_idx, mcl_idx);
531    p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
532    memset(p_mcb, 0, sizeof(btif_hl_mcl_cb_t));
533}
534
535
536/*******************************************************************************
537**
538** Function      btif_hl_find_sdp_idx_using_mdep_filter
539**
540** Description  This function finds the SDP record index using MDEP filter parameters
541**
542** Returns      BOOLEAN
543**
544*******************************************************************************/
545static void btif_hl_reset_mdep_filter(UINT8 app_idx)
546{
547    btif_hl_app_cb_t          *p_acb  =BTIF_HL_GET_APP_CB_PTR(app_idx);
548    p_acb->filter.num_elems = 0;
549}
550
551/*******************************************************************************
552**
553** Function      btif_hl_find_sdp_idx_using_mdep_filter
554**
555** Description  This function finds the SDP record index using MDEP filter parameters
556**
557** Returns      BOOLEAN
558**
559*******************************************************************************/
560static BOOLEAN btif_hl_find_sdp_idx_using_mdep_filter(UINT8 app_idx, UINT8 mcl_idx, UINT8 *p_sdp_idx)
561{
562    btif_hl_app_cb_t          *p_acb  =BTIF_HL_GET_APP_CB_PTR(app_idx);
563    btif_hl_mcl_cb_t          *p_mcb  =BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
564    UINT8                   i, j, num_recs,num_elems, num_mdeps, mdep_cnt, mdep_idx;
565    tBTA_HL_MDEP_ROLE       peer_mdep_role;
566    UINT16                  data_type;
567    tBTA_HL_SDP_MDEP_CFG    *p_mdep;
568    BOOLEAN                 found = FALSE;
569    BOOLEAN                 elem_found;
570
571    BTIF_TRACE_DEBUG0("btif_hl_find_sdp_idx_using_mdep_filter");
572    num_recs = p_mcb->sdp.num_recs;
573    num_elems = p_acb->filter.num_elems;
574    if (!num_elems)
575    {
576        BTIF_TRACE_DEBUG0("btif_hl_find_sdp_idx_using_mdep_filter num_elem=0");
577        *p_sdp_idx = 0;
578        found = TRUE;
579        return found;
580    }
581
582    for (i=0; i<num_recs; i++)
583    {
584        num_mdeps = p_mcb->sdp.sdp_rec[i].num_mdeps;
585        for (j=0; j<num_elems; j++ )
586        {
587            data_type = p_acb->filter.elem[j].data_type;
588            peer_mdep_role = p_acb->filter.elem[j].peer_mdep_role;
589            elem_found = FALSE;
590            mdep_cnt =0;
591            mdep_idx=0;
592            while (!elem_found && mdep_idx < num_mdeps )
593            {
594                p_mdep = &(p_mcb->sdp.sdp_rec[i].mdep_cfg[mdep_idx]);
595                if ( (p_mdep->data_type == data_type) &&
596                     (p_mdep->mdep_role == peer_mdep_role) )
597                {
598                    elem_found = TRUE;
599                }
600                else
601                {
602                    mdep_idx++;
603                }
604            }
605
606            if (!elem_found)
607            {
608                found = FALSE;
609                break;
610            }
611            else
612            {
613                found = TRUE;
614            }
615        }
616
617        if (found)
618        {
619            BTIF_TRACE_DEBUG1("btif_hl_find_sdp_idx_using_mdep_filter found idx=%d",i);
620            *p_sdp_idx = i;
621            break;
622        }
623    }
624
625    BTIF_TRACE_DEBUG3("%s found=%d sdp_idx=%d",__FUNCTION__ , found, *p_sdp_idx);
626
627    btif_hl_reset_mdep_filter(app_idx);
628
629    return found;
630}
631/*******************************************************************************
632**
633** Function      btif_hl_is_reconnect_possible
634**
635** Description  check reconnect is possible or not
636**
637** Returns      BOOLEAN
638**
639*******************************************************************************/
640BOOLEAN btif_hl_is_reconnect_possible(UINT8 app_idx, UINT8 mcl_idx,  int mdep_cfg_idx,
641                                      tBTA_HL_DCH_OPEN_PARAM *p_dch_open_api, tBTA_HL_MDL_ID *p_mdl_id)
642{
643    btif_hl_app_cb_t     *p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
644    btif_hl_mcl_cb_t     *p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
645    tBTA_HL_DCH_CFG      local_cfg = p_dch_open_api->local_cfg;
646    tBTA_HL_DCH_MODE     dch_mode = BTA_HL_DCH_MODE_RELIABLE;
647    BOOLEAN              use_mdl_dch_mode=FALSE;
648    btif_hl_mdl_cfg_t    *p_mdl;
649    btif_hl_mdl_cfg_t    *p_mdl1;
650    UINT8                i, j;
651    BOOLEAN              is_reconnect_ok=FALSE;
652    BOOLEAN              stream_mode_avail=FALSE;
653    UINT16               data_type = p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg.data_cfg[0].data_type;
654    tBTA_HL_MDEP_ID      peer_mdep_id = p_dch_open_api->peer_mdep_id;
655    UINT8                mdl_idx;
656
657
658    BTIF_TRACE_DEBUG4("%s app_idx=%d mcl_idx=%d mdep_cfg_idx=%d",
659                      __FUNCTION__, app_idx, mcl_idx, mdep_cfg_idx  );
660    switch (local_cfg)
661    {
662        case BTA_HL_DCH_CFG_NO_PREF:
663            if (!btif_hl_is_the_first_reliable_existed(app_idx, mcl_idx))
664            {
665                dch_mode = BTA_HL_DCH_MODE_RELIABLE;
666            }
667            else
668            {
669                use_mdl_dch_mode = TRUE;
670            }
671            break;
672        case BTA_HL_DCH_CFG_RELIABLE:
673            dch_mode = BTA_HL_DCH_MODE_RELIABLE;
674            break;
675        case BTA_HL_DCH_CFG_STREAMING:
676            dch_mode = BTA_HL_DCH_MODE_STREAMING;
677            break;
678        default:
679            BTIF_TRACE_ERROR1("Invalid local_cfg=%d",local_cfg );
680            return is_reconnect_ok;
681            break;
682
683    }
684
685    BTIF_TRACE_DEBUG3("local_cfg=%d use_mdl_dch_mode=%d dch_mode=%d ",
686                      local_cfg, use_mdl_dch_mode, dch_mode  );
687
688    for (i=0, p_mdl=&p_acb->mdl_cfg[0] ; i< BTA_HL_NUM_MDL_CFGS; i++, p_mdl++ )
689    {
690        if (p_mdl->base.active &&
691            p_mdl->extra.data_type ==data_type &&
692            (p_mdl->extra.peer_mdep_id != BTA_HL_INVALID_MDEP_ID && p_mdl->extra.peer_mdep_id == peer_mdep_id) &&
693            memcpy(p_mdl->base.peer_bd_addr, p_mcb->bd_addr,sizeof(BD_ADDR) ) &&
694            p_mdl->base.mdl_id &&
695            !btif_hl_find_mdl_idx(app_idx, mcl_idx,p_mdl->base.mdl_id, &mdl_idx))
696        {
697            BTIF_TRACE_DEBUG4("i=%d Matched active=%d   mdl_id =%d, mdl_dch_mode=%d",
698                              i, p_mdl->base.active, p_mdl->base.mdl_id,p_mdl->base.dch_mode);
699            if (!use_mdl_dch_mode)
700            {
701                if (p_mdl->base.dch_mode == dch_mode)
702                {
703                    is_reconnect_ok = TRUE;
704                    *p_mdl_id = p_mdl->base.mdl_id;
705                    BTIF_TRACE_DEBUG2("reconnect is possible dch_mode=%d mdl_id=%d", dch_mode, p_mdl->base.mdl_id );
706                    break;
707                }
708            }
709            else
710            {
711                is_reconnect_ok = TRUE;
712                for (j=i, p_mdl1=&p_acb->mdl_cfg[i]; j< BTA_HL_NUM_MDL_CFGS; j++, p_mdl1++)
713                {
714                    if (p_mdl1->base.active &&
715                        p_mdl1->extra.data_type == data_type &&
716                        (p_mdl1->extra.peer_mdep_id != BTA_HL_INVALID_MDEP_ID && p_mdl1->extra.peer_mdep_id == peer_mdep_id) &&
717                        memcpy(p_mdl1->base.peer_bd_addr, p_mcb->bd_addr,sizeof(BD_ADDR)) &&
718                        p_mdl1->base.dch_mode == BTA_HL_DCH_MODE_STREAMING)
719                    {
720                        stream_mode_avail = TRUE;
721                        BTIF_TRACE_DEBUG1("found streaming mode mdl index=%d", j);
722                        break;
723                    }
724                }
725
726                if (stream_mode_avail)
727                {
728                    dch_mode = BTA_HL_DCH_MODE_STREAMING;
729                    *p_mdl_id = p_mdl1->base.mdl_id;
730                    BTIF_TRACE_DEBUG2("reconnect is ok index=%d dch_mode=streaming  mdl_id=%d", j, *p_mdl_id);
731                    break;
732                }
733                else
734                {
735                    dch_mode= p_mdl->base.dch_mode;
736                    *p_mdl_id = p_mdl->base.mdl_id;
737                    BTIF_TRACE_DEBUG3("reconnect is ok index=%d  dch_mode=%d mdl_id=%d", i,  p_mdl->base.dch_mode, *p_mdl_id);
738                    break;
739
740                }
741            }
742
743        }
744
745    }
746
747    BTIF_TRACE_DEBUG3("is_reconnect_ok  dch_mode=%d mdl_id=%d",is_reconnect_ok, dch_mode, *p_mdl_id);
748    return is_reconnect_ok;
749}
750
751/*******************************************************************************
752**
753** Function      btif_hl_dch_open
754**
755** Description   Process DCH open request using the DCH Open API parameters
756**
757** Returns      BOOLEAN
758**
759*******************************************************************************/
760BOOLEAN btif_hl_dch_open(UINT8 app_id, BD_ADDR bd_addr,
761                         tBTA_HL_DCH_OPEN_PARAM *p_dch_open_api,
762                         int mdep_cfg_idx,
763                         btif_hl_pend_dch_op_t op, int *channel_id){
764    btif_hl_app_cb_t            *p_acb;
765    btif_hl_mcl_cb_t            *p_mcb;
766    btif_hl_pending_chan_cb_t   *p_pcb;
767    UINT8                       app_idx, mcl_idx;
768    BOOLEAN                     status = FALSE;
769    tBTA_HL_MDL_ID              mdl_id;
770    tBTA_HL_DCH_RECONNECT_PARAM reconnect_param;
771
772    BTIF_TRACE_DEBUG2("%s app_id=%d ",
773                      __FUNCTION__, app_id );
774    BTIF_TRACE_DEBUG6("DB [%02x:%02x:%02x:%02x:%02x:%02x]",
775                      bd_addr[0],  bd_addr[1],bd_addr[2],  bd_addr[3], bd_addr[4],  bd_addr[5]);
776
777    if (btif_hl_find_app_idx(app_id, &app_idx))
778    {
779        if (btif_hl_find_mcl_idx(app_idx, bd_addr , &mcl_idx))
780        {
781            p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
782
783            p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
784            if (!p_pcb->in_use)
785            {
786                p_mcb->req_ctrl_psm = p_dch_open_api->ctrl_psm;
787
788                p_pcb->in_use = TRUE;
789                *channel_id       =
790                p_pcb->channel_id =  (int) btif_hl_get_next_channel_id(app_id);
791                p_pcb->cb_state = BTIF_HL_CHAN_CB_STATE_CONNECTING_PENDING;
792                p_pcb->mdep_cfg_idx = mdep_cfg_idx;
793                memcpy(p_pcb->bd_addr, bd_addr, sizeof(BD_ADDR));
794                p_pcb->op = op;
795
796                if (p_mcb->sdp.num_recs)
797                {
798                    if (p_mcb->valid_sdp_idx)
799                    {
800                        p_dch_open_api->ctrl_psm  = p_mcb->ctrl_psm;
801                    }
802
803                    if (!btif_hl_is_reconnect_possible(app_idx, mcl_idx, mdep_cfg_idx, p_dch_open_api, &mdl_id ))
804                    {
805
806                        BTIF_TRACE_DEBUG0("Issue DCH open" );
807                        BTA_HlDchOpen(p_mcb->mcl_handle, p_dch_open_api);
808                    }
809                    else
810                    {
811                        reconnect_param.ctrl_psm = p_mcb->ctrl_psm;
812                        reconnect_param.mdl_id = mdl_id;;
813                        BTIF_TRACE_DEBUG2("Issue Reconnect ctrl_psm=0x%x mdl_id=0x%x",reconnect_param.ctrl_psm, reconnect_param.mdl_id   );
814                        BTA_HlDchReconnect(p_mcb->mcl_handle, &reconnect_param);
815                    }
816
817                    status = TRUE;
818                }
819                else
820                {
821                    p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
822                    p_mcb->cch_oper = BTIF_HL_CCH_OP_DCH_OPEN;
823                    BTA_HlSdpQuery(app_id,p_acb->app_handle, bd_addr);
824                    status = TRUE;
825                }
826            }
827        }
828    }
829
830    BTIF_TRACE_DEBUG1("status=%d ", status);
831    return status;
832}
833/*******************************************************************************
834**
835** Function      btif_hl_copy_bda
836**
837** Description  copy bt_bdaddr_t to BD_ADDR format
838**
839** Returns      void
840**
841*******************************************************************************/
842void btif_hl_copy_bda(bt_bdaddr_t *bd_addr, BD_ADDR  bda){
843    UINT8 i;
844    for (i=0; i<6; i++)
845    {
846        bd_addr->address[i] = bda[i] ;
847    }
848}
849/*******************************************************************************
850**
851** Function      btif_hl_copy_bda
852**
853** Description  display bt_bdaddr_t
854**
855** Returns      BOOLEAN
856**
857*******************************************************************************/
858void btif_hl_display_bt_bda(bt_bdaddr_t *bd_addr){
859    BTIF_TRACE_DEBUG6("DB [%02x:%02x:%02x:%02x:%02x:%02x]",
860                      bd_addr->address[0],   bd_addr->address[1], bd_addr->address[2],
861                      bd_addr->address[3],  bd_addr->address[4],   bd_addr->address[5]);
862}
863
864/*******************************************************************************
865**
866** Function         btif_hl_dch_abort
867**
868** Description      Process DCH abort request
869**
870** Returns          Nothing
871**
872*******************************************************************************/
873void  btif_hl_dch_abort(UINT8 app_idx, UINT8 mcl_idx){
874    btif_hl_mcl_cb_t      *p_mcb;
875
876    BTIF_TRACE_DEBUG3("%s app_idx=%d mcl_idx=%d",__FUNCTION__, app_idx, mcl_idx );
877    p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
878    if (p_mcb->is_connected)
879    {
880        BTA_HlDchAbort(p_mcb->mcl_handle);
881    }
882    else
883    {
884        p_mcb->pcb.abort_pending = TRUE;
885    }
886
887}
888/*******************************************************************************
889**
890** Function      btif_hl_cch_open
891**
892** Description   Process CCH open request
893**
894** Returns     Nothing
895**
896*******************************************************************************/
897BOOLEAN btif_hl_cch_open(UINT8 app_id, BD_ADDR bd_addr, UINT16 ctrl_psm,
898                         int mdep_cfg_idx,
899                         btif_hl_pend_dch_op_t op, int *channel_id){
900
901    btif_hl_app_cb_t            *p_acb;
902    btif_hl_mcl_cb_t            *p_mcb;
903    btif_hl_pending_chan_cb_t   *p_pcb;
904    UINT8                       app_idx, mcl_idx, chan_idx;
905    BOOLEAN                     status = TRUE;
906
907    BTIF_TRACE_DEBUG5("%s app_id=%d ctrl_psm=%d mdep_cfg_idx=%d op=%d",
908                      __FUNCTION__, app_id, ctrl_psm, mdep_cfg_idx, op);
909    BTIF_TRACE_DEBUG6("DB [%02x:%02x:%02x:%02x:%02x:%02x]",
910                      bd_addr[0],  bd_addr[1],bd_addr[2],  bd_addr[3], bd_addr[4],  bd_addr[5]);
911
912    if (btif_hl_find_app_idx(app_id, &app_idx))
913    {
914        p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
915
916        if (!btif_hl_find_mcl_idx(app_idx, bd_addr, &mcl_idx))
917        {
918            if (btif_hl_find_avail_mcl_idx(app_idx, &mcl_idx))
919            {
920                p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
921                memset(p_mcb,0, sizeof(btif_hl_mcl_cb_t));
922                p_mcb->in_use = TRUE;
923                bdcpy(p_mcb->bd_addr, bd_addr);
924
925                if (!ctrl_psm)
926                {
927                    p_mcb->cch_oper = BTIF_HL_CCH_OP_MDEP_FILTERING;
928                }
929                else
930                {
931                    p_mcb->cch_oper        = BTIF_HL_CCH_OP_MATCHED_CTRL_PSM;
932                    p_mcb->req_ctrl_psm    = ctrl_psm;
933                }
934
935                p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
936                p_pcb->in_use = TRUE;
937                p_pcb->mdep_cfg_idx = mdep_cfg_idx;
938                memcpy(p_pcb->bd_addr, bd_addr, sizeof(BD_ADDR));
939                p_pcb->op = op;
940
941                switch (op)
942                {
943                    case BTIF_HL_PEND_DCH_OP_OPEN:
944                        *channel_id       =
945                        p_pcb->channel_id =  (int) btif_hl_get_next_channel_id(app_id);
946                        p_pcb->cb_state = BTIF_HL_CHAN_CB_STATE_CONNECTING_PENDING;
947                        break;
948                    case BTIF_HL_PEND_DCH_OP_DELETE_MDL:
949                        p_pcb->channel_id =  p_acb->delete_mdl.channel_id;
950                        p_pcb->cb_state = BTIF_HL_CHAN_CB_STATE_DESTROYED_PENDING;
951                        break;
952                    default:
953                        break;
954                }
955                BTA_HlSdpQuery(app_id,p_acb->app_handle, bd_addr);
956            }
957            else
958            {
959                status = FALSE;
960                BTIF_TRACE_ERROR0("Open CCH request discarded- No mcl cb");
961            }
962        }
963        else
964        {
965            status = FALSE;
966            BTIF_TRACE_ERROR0("Open CCH request discarded- already in USE");
967        }
968    }
969    else
970    {
971        status = FALSE;
972        BTIF_TRACE_ERROR1("Invalid app_id=%d", app_id);
973    }
974
975    if (channel_id)
976    {
977        BTIF_TRACE_DEBUG2("status=%d channel_id=0x%08x", status, *channel_id);
978    }
979    else
980    {
981        BTIF_TRACE_DEBUG1("status=%d ", status);
982    }
983    return status;
984}
985
986
987/*******************************************************************************
988**
989** Function      btif_hl_find_mdl_idx_using_handle
990**
991** Description  Find the MDL index using channel id
992**
993** Returns      BOOLEAN
994**
995*******************************************************************************/
996BOOLEAN btif_hl_find_mdl_cfg_idx_using_channel_id(int channel_id,
997                                                  UINT8 *p_app_idx,
998                                                  UINT8 *p_mdl_cfg_idx){
999    btif_hl_app_cb_t      *p_acb;
1000    btif_hl_mdl_cfg_t     *p_mdl;
1001    BOOLEAN found=FALSE;
1002    UINT8 i,j;
1003    int mdl_cfg_channel_id;
1004
1005    for (i=0; i < BTA_HL_NUM_APPS ; i ++)
1006    {
1007        p_acb =BTIF_HL_GET_APP_CB_PTR(i);
1008        for (j=0; j< BTA_HL_NUM_MDL_CFGS; j++)
1009        {
1010            p_mdl =BTIF_HL_GET_MDL_CFG_PTR(i,j);
1011            mdl_cfg_channel_id = *(BTIF_HL_GET_MDL_CFG_CHANNEL_ID_PTR(i,j));
1012            if (p_acb->in_use &&
1013                p_mdl->base.active &&
1014                (mdl_cfg_channel_id == channel_id))
1015            {
1016                found = TRUE;
1017                *p_app_idx = i;
1018                *p_mdl_cfg_idx =j;
1019                break;
1020            }
1021        }
1022    }
1023
1024    BTIF_TRACE_EVENT5("%s found=%d channel_id=0x%08x, app_idx=%d mdl_cfg_idx=%d  ",
1025                      __FUNCTION__,found,channel_id, i,j );
1026    return found;
1027}
1028/*******************************************************************************
1029**
1030** Function      btif_hl_find_mdl_idx_using_handle
1031**
1032** Description  Find the MDL index using channel id
1033**
1034** Returns      BOOLEAN
1035**
1036*******************************************************************************/
1037BOOLEAN btif_hl_find_mdl_idx_using_channel_id(int channel_id,
1038                                              UINT8 *p_app_idx,UINT8 *p_mcl_idx,
1039                                              UINT8 *p_mdl_idx){
1040    btif_hl_app_cb_t      *p_acb;
1041    btif_hl_mcl_cb_t      *p_mcb;
1042    btif_hl_mdl_cb_t      *p_dcb;
1043    BOOLEAN found=FALSE;
1044    UINT8 i,j,k;
1045
1046    for (i=0; i < BTA_HL_NUM_APPS ; i ++)
1047    {
1048        p_acb =BTIF_HL_GET_APP_CB_PTR(i);
1049        for (j=0; j< BTA_HL_NUM_MCLS; j++)
1050        {
1051            p_mcb =BTIF_HL_GET_MCL_CB_PTR(i,j);
1052            for (k=0; k< BTA_HL_NUM_MDLS_PER_MCL; k++)
1053            {
1054                p_dcb =BTIF_HL_GET_MDL_CB_PTR(i,j,k);
1055                if (p_acb->in_use &&
1056                    p_mcb->in_use &&
1057                    p_dcb->in_use &&
1058                    (p_dcb->channel_id == channel_id))
1059                {
1060                    found = TRUE;
1061                    *p_app_idx = i;
1062                    *p_mcl_idx =j;
1063                    *p_mdl_idx = k;
1064                    break;
1065                }
1066            }
1067        }
1068    }
1069    BTIF_TRACE_DEBUG5("%s found=%d app_idx=%d mcl_idx=%d mdl_idx=%d  ",
1070                      __FUNCTION__,found,i,j,k );
1071    return found;
1072}
1073
1074/*******************************************************************************
1075**
1076** Function      btif_hl_find_channel_id_using_mdl_id
1077**
1078** Description  Find channel id using mdl_id'
1079**
1080** Returns      BOOLEAN
1081*********************************************************************************/
1082BOOLEAN btif_hl_find_channel_id_using_mdl_id(UINT8 app_idx, tBTA_HL_MDL_ID mdl_id,
1083                                            int *p_channel_id){
1084    btif_hl_app_cb_t      *p_acb;
1085    btif_hl_mdl_cfg_t     *p_mdl;
1086    BOOLEAN found=FALSE;
1087    UINT8 j=0;
1088    int mdl_cfg_channel_id;
1089    p_acb =BTIF_HL_GET_APP_CB_PTR(app_idx);
1090    if (p_acb && p_acb->in_use)
1091        {
1092            for (j=0; j< BTA_HL_NUM_MDL_CFGS; j++)
1093                {
1094                    p_mdl =BTIF_HL_GET_MDL_CFG_PTR(app_idx,j);
1095                    mdl_cfg_channel_id = *(BTIF_HL_GET_MDL_CFG_CHANNEL_ID_PTR(app_idx,j));
1096                    if ( p_mdl->base.active && (p_mdl->base.mdl_id == mdl_id))
1097                    {
1098                            found = TRUE;
1099                            *p_channel_id = mdl_cfg_channel_id;
1100                            break;
1101                    }
1102                }
1103        }
1104    BTIF_TRACE_EVENT6("%s found=%d channel_id=0x%08x, mdl_id=0x%x app_idx=%d mdl_cfg_idx=%d  ",
1105                    __FUNCTION__,found,*p_channel_id,mdl_id, app_idx,j );
1106    return found;
1107}
1108
1109
1110/*******************************************************************************
1111**
1112** Function      btif_hl_find_mdl_idx_using_handle
1113**
1114** Description  Find the MDL index using handle
1115**
1116** Returns      BOOLEAN
1117**
1118*******************************************************************************/
1119BOOLEAN btif_hl_find_mdl_idx_using_handle(tBTA_HL_MDL_HANDLE mdl_handle,
1120                                          UINT8 *p_app_idx,UINT8 *p_mcl_idx,
1121                                          UINT8 *p_mdl_idx){
1122    btif_hl_app_cb_t      *p_acb;
1123    btif_hl_mcl_cb_t      *p_mcb;
1124    btif_hl_mdl_cb_t      *p_dcb;
1125    BOOLEAN found=FALSE;
1126    UINT8 i,j,k;
1127
1128    for (i=0; i < BTA_HL_NUM_APPS ; i ++)
1129    {
1130        p_acb =BTIF_HL_GET_APP_CB_PTR(i);
1131        for (j=0; j< BTA_HL_NUM_MCLS; j++)
1132        {
1133            p_mcb =BTIF_HL_GET_MCL_CB_PTR(i,j);
1134            for (k=0; k< BTA_HL_NUM_MDLS_PER_MCL; k++)
1135            {
1136                p_dcb =BTIF_HL_GET_MDL_CB_PTR(i,j,k);
1137                if (p_acb->in_use &&
1138                    p_mcb->in_use &&
1139                    p_dcb->in_use &&
1140                    (p_dcb->mdl_handle == mdl_handle))
1141                {
1142                    found = TRUE;
1143                    *p_app_idx = i;
1144                    *p_mcl_idx =j;
1145                    *p_mdl_idx = k;
1146                    break;
1147                }
1148            }
1149        }
1150    }
1151
1152
1153    BTIF_TRACE_EVENT5("%s found=%d app_idx=%d mcl_idx=%d mdl_idx=%d  ",
1154                      __FUNCTION__,found,i,j,k );
1155    return found;
1156}
1157/*******************************************************************************
1158**
1159** Function        btif_hl_find_peer_mdep_id
1160**
1161** Description      Find the peer MDEP ID from the received SPD records
1162**
1163** Returns          BOOLEAN
1164**
1165*******************************************************************************/
1166static BOOLEAN btif_hl_find_peer_mdep_id(UINT8 app_id, BD_ADDR bd_addr,
1167                                         tBTA_HL_MDEP_ROLE local_mdep_role,
1168                                         UINT16 data_type,
1169                                         tBTA_HL_MDEP_ID *p_peer_mdep_id){
1170    UINT8               app_idx, mcl_idx;
1171    btif_hl_app_cb_t     *p_acb;
1172    btif_hl_mcl_cb_t     *p_mcb;
1173    tBTA_HL_SDP_REC     *p_rec;
1174    UINT8               i, num_mdeps;
1175    BOOLEAN             found = FALSE;
1176    tBTA_HL_MDEP_ROLE   peer_mdep_role;
1177
1178
1179    BTIF_TRACE_DEBUG4("%s app_id=%d local_mdep_role=%d, data_type=%d",
1180                      __FUNCTION__, app_id, local_mdep_role, data_type);
1181
1182    BTIF_TRACE_DEBUG6("DB [%02x:%02x:%02x:%02x:%02x:%02x]",
1183                      bd_addr[0],  bd_addr[1],
1184                      bd_addr[2],  bd_addr[3],
1185                      bd_addr[4],  bd_addr[5]);
1186
1187
1188    BTIF_TRACE_DEBUG1("local_mdep_role=%d", local_mdep_role);
1189    BTIF_TRACE_DEBUG1("data_type=%d", data_type);
1190
1191    if (local_mdep_role == BTA_HL_MDEP_ROLE_SINK)
1192        peer_mdep_role = BTA_HL_MDEP_ROLE_SOURCE;
1193    else
1194        peer_mdep_role = BTA_HL_MDEP_ROLE_SINK;
1195
1196    if (btif_hl_find_app_idx(app_id, &app_idx) )
1197    {
1198        p_acb  = BTIF_HL_GET_APP_CB_PTR(app_idx);
1199        if (btif_hl_find_mcl_idx(app_idx, bd_addr, &mcl_idx))
1200        {
1201            p_mcb  =BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1202
1203            BTIF_TRACE_DEBUG2("app_idx=%d mcl_idx=%d",app_idx, mcl_idx);
1204            BTIF_TRACE_DEBUG2("valid_spd_idx=%d sdp_idx=%d",p_mcb->valid_sdp_idx, p_mcb->sdp_idx);
1205            if (p_mcb->valid_sdp_idx)
1206            {
1207                p_rec = &p_mcb->sdp.sdp_rec[p_mcb->sdp_idx];
1208                num_mdeps = p_rec->num_mdeps;
1209                BTIF_TRACE_DEBUG1("num_mdeps=%d", num_mdeps);
1210
1211                for (i=0; i< num_mdeps; i++)
1212                {
1213                    BTIF_TRACE_DEBUG2("p_rec->mdep_cfg[%d].mdep_role=%d",i, p_rec->mdep_cfg[i].mdep_role);
1214                    BTIF_TRACE_DEBUG2("p_rec->mdep_cfg[%d].data_type =%d",i, p_rec->mdep_cfg[i].data_type );
1215                    if ((p_rec->mdep_cfg[i].mdep_role == peer_mdep_role) &&
1216                        (p_rec->mdep_cfg[i].data_type == data_type))
1217                    {
1218                        found = TRUE;
1219                        *p_peer_mdep_id = p_rec->mdep_cfg[i].mdep_id;
1220                        break;
1221                    }
1222                }
1223            }
1224        }
1225    }
1226
1227    BTIF_TRACE_DEBUG2("found =%d  *p_peer_mdep_id=%d", found,  *p_peer_mdep_id);
1228
1229    return found;
1230}
1231/*******************************************************************************
1232**
1233** Function        btif_hl_find_local_mdep_id
1234**
1235** Description      Find the local MDEP ID from the MDEP configuration
1236**
1237** Returns          BOOLEAN
1238**
1239*******************************************************************************/
1240static BOOLEAN btif_hl_find_local_mdep_id(UINT8 app_id,
1241                                          tBTA_HL_MDEP_ROLE local_mdep_role,
1242                                          UINT16 mdep_data_type,
1243                                          tBTA_HL_MDEP_ID *p_local_mdep_id){
1244    UINT8 app_idx;
1245    btif_hl_app_cb_t      *p_acb;
1246    UINT8  i,j;
1247    BOOLEAN found = FALSE;
1248
1249    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
1250
1251    if (btif_hl_find_app_idx(app_id, &app_idx) )
1252    {
1253        p_acb  =BTIF_HL_GET_APP_CB_PTR(app_idx);
1254
1255        for (i=0; i< p_acb->sup_feature.num_of_mdeps; i++)
1256        {
1257            if (p_acb->sup_feature.mdep[i].mdep_cfg.mdep_role == local_mdep_role )
1258            {
1259                for (j=0; j< p_acb->sup_feature.mdep[i].mdep_cfg.num_of_mdep_data_types; j++)
1260                {
1261                    if ( p_acb->sup_feature.mdep[i].mdep_cfg.data_cfg[j].data_type == mdep_data_type)
1262                    {
1263                        found = TRUE;
1264                        *p_local_mdep_id = p_acb->sup_feature.mdep[i].mdep_id;
1265                        return found;
1266                    }
1267                }
1268            }
1269        }
1270
1271
1272    }
1273    BTIF_TRACE_DEBUG2("found=%d local mdep id=%d", found, *p_local_mdep_id );
1274    return found;
1275}
1276
1277/*******************************************************************************
1278**
1279** Function      btif_hl_find_mdep_cfg_idx
1280**
1281** Description  Find the MDEP configuration index using local MDEP_ID
1282**
1283** Returns      BOOLEAN
1284**
1285*******************************************************************************/
1286static  BOOLEAN btif_hl_find_mdep_cfg_idx(UINT8 app_idx,  tBTA_HL_MDEP_ID local_mdep_id,
1287                                          UINT8 *p_mdep_cfg_idx){
1288    btif_hl_app_cb_t      *p_acb =BTIF_HL_GET_APP_CB_PTR(app_idx);
1289    tBTA_HL_SUP_FEATURE     *p_sup_feature= &p_acb->sup_feature;
1290    BOOLEAN found =FALSE;
1291    UINT8 i;
1292
1293    for (i=0; i< p_sup_feature->num_of_mdeps; i++)
1294    {
1295        BTIF_TRACE_DEBUG2("btif_hl_find_mdep_cfg_idx: mdep_id=%d app_idx = %d",
1296                    p_sup_feature->mdep[i].mdep_id,app_idx);
1297        if ( p_sup_feature->mdep[i].mdep_id == local_mdep_id)
1298        {
1299            found = TRUE;
1300            *p_mdep_cfg_idx = i;
1301            break;
1302        }
1303    }
1304
1305    BTIF_TRACE_DEBUG5("%s found=%d mdep_idx=%d local_mdep_id=%d app_idx=%d ",
1306                      __FUNCTION__, found,i, local_mdep_id,app_idx);
1307    return found;
1308}
1309
1310
1311
1312/*******************************************************************************
1313**
1314** Function      btif_hl_find_mcl_idx
1315**
1316** Description  Find the MCL index using BD address
1317**
1318** Returns      BOOLEAN
1319**
1320*******************************************************************************/
1321BOOLEAN btif_hl_find_mcl_idx(UINT8 app_idx, BD_ADDR p_bd_addr, UINT8 *p_mcl_idx){
1322    BOOLEAN found=FALSE;
1323    UINT8 i;
1324    btif_hl_app_cb_t  *p_acb =BTIF_HL_GET_APP_CB_PTR(app_idx);
1325    btif_hl_mcl_cb_t  *p_mcb;
1326
1327    for (i=0; i < BTA_HL_NUM_MCLS ; i ++)
1328    {
1329        p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, i);
1330        if (p_mcb->in_use &&
1331            (!memcmp (p_mcb->bd_addr, p_bd_addr, BD_ADDR_LEN)))
1332        {
1333            found = TRUE;
1334            *p_mcl_idx = i;
1335            break;
1336        }
1337    }
1338
1339
1340    BTIF_TRACE_DEBUG3("%s found=%d idx=%d",__FUNCTION__, found, i);
1341    return found;
1342}
1343/*******************************************************************************
1344**
1345** Function         btif_hl_init
1346**
1347** Description      HL initialization function.
1348**
1349** Returns          void
1350**
1351*******************************************************************************/
1352static void btif_hl_init(void){
1353    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
1354    memset(p_btif_hl_cb, 0, sizeof(btif_hl_cb_t));
1355    btif_hl_init_next_app_id();
1356    btif_hl_init_next_channel_id();
1357}
1358/*******************************************************************************
1359**
1360** Function         btif_hl_disable
1361**
1362** Description      Disable initialization function.
1363**
1364** Returns          void
1365**
1366*******************************************************************************/
1367static void btif_hl_disable(void){
1368    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
1369
1370    if ((p_btif_hl_cb->state != BTIF_HL_STATE_DISABLING) &&
1371        (p_btif_hl_cb->state != BTIF_HL_STATE_DISABLED))
1372    {
1373        btif_hl_set_state(BTIF_HL_STATE_DISABLING);
1374        BTA_HlDisable();
1375    }
1376}
1377/*******************************************************************************
1378**
1379** Function      btif_hl_is_no_active_app
1380**
1381** Description  Find whether or not  any APP is still in use
1382**
1383** Returns      BOOLEAN
1384**
1385*******************************************************************************/
1386static BOOLEAN btif_hl_is_no_active_app(void){
1387    BOOLEAN no_active_app = TRUE;
1388    UINT8 i;
1389
1390    for (i=0; i < BTA_HL_NUM_APPS ; i ++)
1391    {
1392        if (btif_hl_cb.acb[i].in_use)
1393        {
1394            no_active_app = FALSE;
1395            break;
1396        }
1397    }
1398
1399    BTIF_TRACE_DEBUG2("%s no_active_app=%d  ", __FUNCTION__, no_active_app );
1400    return no_active_app;
1401}
1402
1403/*******************************************************************************
1404**
1405** Function      btif_hl_free_app_idx
1406**
1407** Description free an application control block
1408**
1409** Returns      void
1410**
1411*******************************************************************************/
1412static void btif_hl_free_app_idx(UINT8 app_idx){
1413
1414    if ((app_idx < BTA_HL_NUM_APPS) && btif_hl_cb.acb[app_idx].in_use )
1415    {
1416        btif_hl_cb.acb[app_idx].in_use = FALSE;
1417        memset (&btif_hl_cb.acb[app_idx], 0, sizeof(btif_hl_app_cb_t));
1418    }
1419}
1420/*******************************************************************************
1421**
1422** Function      btif_hl_set_state
1423**
1424** Description set HL state
1425**
1426** Returns      void
1427**
1428*******************************************************************************/
1429static void btif_hl_set_state(btif_hl_state_t state){
1430    BTIF_TRACE_DEBUG2("btif_hl_set_state:  %d ---> %d ", p_btif_hl_cb->state, state);
1431    p_btif_hl_cb->state = state;
1432}
1433
1434/*******************************************************************************
1435**
1436** Function      btif_hl_set_state
1437**
1438** Description get HL state
1439**
1440** Returns      btif_hl_state_t
1441**
1442*******************************************************************************/
1443
1444static btif_hl_state_t btif_hl_get_state(void){
1445    BTIF_TRACE_DEBUG1("btif_hl_get_state:  %d   ", p_btif_hl_cb->state);
1446    return p_btif_hl_cb->state;
1447}
1448
1449/*******************************************************************************
1450**
1451** Function      btif_hl_find_data_type_idx
1452**
1453** Description  Find the index in the data type table
1454**
1455** Returns      BOOLEAN
1456**
1457*******************************************************************************/
1458static BOOLEAN  btif_hl_find_data_type_idx(UINT16 data_type, UINT8 *p_idx){
1459    BOOLEAN found = FALSE;
1460    UINT8 i;
1461
1462    for (i=0; i< BTIF_HL_DATA_TABLE_SIZE; i++ )
1463    {
1464        if (data_type_table[i].data_type == data_type)
1465        {
1466            found = TRUE;
1467            *p_idx= i;
1468            break;
1469        }
1470    }
1471
1472    BTIF_TRACE_DEBUG4("%s found=%d, data_type=0x%x idx=%d", __FUNCTION__, found, data_type, i);
1473    return found;
1474}
1475
1476/*******************************************************************************
1477**
1478** Function      btif_hl_get_max_tx_apdu_size
1479**
1480** Description  Find the maximum TX APDU size for the specified data type and
1481**              MDEP role
1482**
1483** Returns      UINT16
1484**
1485*******************************************************************************/
1486UINT16  btif_hl_get_max_tx_apdu_size(tBTA_HL_MDEP_ROLE mdep_role,
1487                                     UINT16 data_type ){
1488    UINT8 idx;
1489    UINT16 max_tx_apdu_size =0;
1490
1491    if (btif_hl_find_data_type_idx(data_type, &idx))
1492    {
1493        if (mdep_role == BTA_HL_MDEP_ROLE_SOURCE)
1494        {
1495            max_tx_apdu_size = data_type_table[idx].max_tx_apdu_size;
1496        }
1497        else
1498        {
1499            max_tx_apdu_size = data_type_table[idx].max_rx_apdu_size;
1500        }
1501    }
1502    else
1503    {
1504        if (mdep_role == BTA_HL_MDEP_ROLE_SOURCE)
1505        {
1506            max_tx_apdu_size = BTIF_HL_DEFAULT_SRC_TX_APDU_SIZE;
1507        }
1508        else
1509        {
1510            max_tx_apdu_size = BTIF_HL_DEFAULT_SRC_RX_APDU_SIZE;
1511        }
1512
1513
1514    }
1515
1516    BTIF_TRACE_DEBUG4("%s mdep_role=%d data_type=0x%4x size=%d",
1517                      __FUNCTION__, mdep_role, data_type, max_tx_apdu_size);
1518    return max_tx_apdu_size;
1519}
1520
1521
1522/*******************************************************************************
1523**
1524** Function      btif_hl_get_max_rx_apdu_size
1525**
1526** Description  Find the maximum RX APDU size for the specified data type and
1527**              MDEP role
1528**
1529** Returns      UINT16
1530**
1531*******************************************************************************/
1532UINT16  btif_hl_get_max_rx_apdu_size(tBTA_HL_MDEP_ROLE mdep_role,
1533                                     UINT16 data_type ){
1534    UINT8  idx;
1535    UINT16 max_rx_apdu_size =0;
1536
1537    if (btif_hl_find_data_type_idx(data_type, &idx))
1538    {
1539        if (mdep_role == BTA_HL_MDEP_ROLE_SOURCE)
1540        {
1541            max_rx_apdu_size = data_type_table[idx].max_rx_apdu_size;
1542        }
1543        else
1544        {
1545            max_rx_apdu_size = data_type_table[idx].max_tx_apdu_size;
1546        }
1547    }
1548    else
1549    {
1550        if (mdep_role == BTA_HL_MDEP_ROLE_SOURCE)
1551        {
1552            max_rx_apdu_size = BTIF_HL_DEFAULT_SRC_RX_APDU_SIZE;
1553        }
1554        else
1555        {
1556            max_rx_apdu_size = BTIF_HL_DEFAULT_SRC_TX_APDU_SIZE;
1557        }
1558    }
1559
1560
1561    BTIF_TRACE_DEBUG4("%s mdep_role=%d data_type=0x%4x size=%d",
1562                      __FUNCTION__, mdep_role, data_type, max_rx_apdu_size);
1563
1564    return max_rx_apdu_size;
1565}
1566
1567/*******************************************************************************
1568**
1569** Function      btif_hl_if_channel_setup_pending
1570**
1571** Description
1572**
1573** Returns      BOOLEAN
1574**
1575*******************************************************************************/
1576
1577static BOOLEAN btif_hl_get_bta_mdep_role(bthl_mdep_role_t mdep, tBTA_HL_MDEP_ROLE *p){
1578    BOOLEAN status = TRUE;
1579    switch (mdep)
1580    {
1581        case BTHL_MDEP_ROLE_SOURCE:
1582            *p = BTA_HL_MDEP_ROLE_SOURCE;
1583            break;
1584        case BTHL_MDEP_ROLE_SINK:
1585            *p = BTA_HL_MDEP_ROLE_SINK;
1586            break;
1587        default:
1588            status = FALSE;
1589            break;
1590    }
1591
1592    BTIF_TRACE_DEBUG4("%s status=%d bta_mdep_role=%d (%d:btif)",
1593                      __FUNCTION__, status, *p, mdep);
1594    return status;
1595}
1596/*******************************************************************************
1597**
1598** Function btif_hl_get_bta_channel_type
1599**
1600** Description convert bthl channel type to BTA DCH channel type
1601**
1602** Returns BOOLEAN
1603**
1604*******************************************************************************/
1605
1606static BOOLEAN btif_hl_get_bta_channel_type(bthl_channel_type_t channel_type, tBTA_HL_DCH_CFG *p){
1607    BOOLEAN status = TRUE;
1608    switch (channel_type)
1609    {
1610        case BTHL_CHANNEL_TYPE_RELIABLE:
1611            *p = BTA_HL_DCH_CFG_RELIABLE;
1612            break;
1613        case BTHL_CHANNEL_TYPE_STREAMING:
1614            *p = BTA_HL_DCH_CFG_STREAMING;
1615            break;
1616        case BTHL_CHANNEL_TYPE_ANY:
1617            *p = BTA_HL_DCH_CFG_NO_PREF;
1618            break;
1619        default:
1620            status = FALSE;
1621            break;
1622    }
1623    BTIF_TRACE_DEBUG3("%s status = %d BTA DCH CFG=%d (1-rel 2-strm",
1624                      __FUNCTION__, status, *p);
1625    return status;
1626}
1627/*******************************************************************************
1628**
1629** Function btif_hl_get_next_app_id
1630**
1631** Description get next applcation id
1632**
1633** Returns UINT8
1634**
1635*******************************************************************************/
1636
1637static UINT8 btif_hl_get_next_app_id(){
1638    UINT8 next_app_id = btif_hl_cb.next_app_id;
1639
1640    btif_hl_cb.next_app_id++;
1641    return next_app_id;
1642}
1643/*******************************************************************************
1644**
1645** Function btif_hl_get_next_channel_id
1646**
1647** Description get next channel id
1648**
1649** Returns int
1650**
1651*******************************************************************************/
1652static int btif_hl_get_next_channel_id(UINT8 app_id){
1653    UINT16 next_channel_id = btif_hl_cb.next_channel_id;
1654    int channel_id;
1655    btif_hl_cb.next_channel_id++;
1656    channel_id = (app_id << 16) + next_channel_id;
1657    BTIF_TRACE_DEBUG4("%s channel_id=0x%08x, app_id=0x%02x next_channel_id=0x%04x", __FUNCTION__,
1658                      channel_id, app_id,  next_channel_id);
1659    return channel_id;
1660}
1661/*******************************************************************************
1662**
1663** Function btif_hl_get_app_id
1664**
1665** Description get the applicaiton id associated with the channel id
1666**
1667** Returns UINT8
1668**
1669*******************************************************************************/
1670
1671static UINT8 btif_hl_get_app_id(int channel_id){
1672    UINT8 app_id =(UINT8) (channel_id >> 16);
1673    BTIF_TRACE_DEBUG3("%s channel_id=0x%08x, app_id=0x%02x ", __FUNCTION__,channel_id, app_id);
1674    return app_id;
1675}
1676/*******************************************************************************
1677**
1678** Function btif_hl_init_next_app_id
1679**
1680** Description initialize the application id
1681**
1682** Returns void
1683**
1684*******************************************************************************/
1685static void btif_hl_init_next_app_id(void){
1686    btif_hl_cb.next_app_id = 1;
1687}
1688/*******************************************************************************
1689**
1690** Function btif_hl_init_next_channel_id
1691**
1692** Description initialize the channel id
1693**
1694** Returns void
1695**
1696*******************************************************************************/
1697static void btif_hl_init_next_channel_id(void){
1698    btif_hl_cb.next_channel_id = 1;
1699}
1700
1701
1702/*******************************************************************************
1703**
1704** Function      btif_hl_find_app_idx_using_handle
1705**
1706** Description  Find the applicaiton index using handle
1707**
1708** Returns      BOOLEAN
1709**
1710*******************************************************************************/
1711BOOLEAN btif_hl_find_app_idx_using_handle(tBTA_HL_APP_HANDLE app_handle,
1712                                          UINT8 *p_app_idx){
1713    BOOLEAN found=FALSE;
1714    UINT8 i;
1715
1716    for (i=0; i < BTA_HL_NUM_APPS ; i ++)
1717    {
1718        if (btif_hl_cb.acb[i].in_use &&
1719            (btif_hl_cb.acb[i].app_handle == app_handle))
1720        {
1721            found = TRUE;
1722            *p_app_idx = i;
1723            break;
1724        }
1725    }
1726
1727    BTIF_TRACE_EVENT4("%s status=%d handle=%d app_idx=%d ",
1728                      __FUNCTION__, found, app_handle , i);
1729
1730    return found;
1731}
1732
1733/*******************************************************************************
1734**
1735** Function      btif_hl_find_app_idx_using_app_id
1736**
1737** Description  Find the applicaiton index using app_id
1738**
1739** Returns      BOOLEAN
1740**
1741*******************************************************************************/
1742BOOLEAN btif_hl_find_app_idx_using_app_id(UINT8 app_id,
1743                                          UINT8 *p_app_idx){
1744    BOOLEAN found=FALSE;
1745    UINT8 i;
1746
1747    for (i=0; i < BTA_HL_NUM_APPS ; i ++)
1748    {
1749        if (btif_hl_cb.acb[i].in_use &&
1750            (btif_hl_cb.acb[i].app_id == app_id))
1751        {
1752            found = TRUE;
1753            *p_app_idx = i;
1754            break;
1755        }
1756    }
1757
1758    BTIF_TRACE_EVENT4("%s found=%d app_id=%d app_idx=%d ",
1759                      __FUNCTION__, found, app_id , i);
1760
1761    return found;
1762}
1763
1764/*******************************************************************************
1765**
1766** Function      btif_hl_find_mcl_idx_using_handle
1767**
1768** Description  Find the MCL index using handle
1769**
1770** Returns      BOOLEAN
1771**
1772*******************************************************************************/
1773BOOLEAN btif_hl_find_mcl_idx_using_handle( tBTA_HL_MCL_HANDLE mcl_handle,
1774                                           UINT8 *p_app_idx, UINT8 *p_mcl_idx){
1775    btif_hl_app_cb_t  *p_acb;
1776    BOOLEAN         found=FALSE;
1777    UINT8 i,j;
1778
1779    for (i=0; i<BTA_HL_NUM_APPS; i++)
1780    {
1781        p_acb =BTIF_HL_GET_APP_CB_PTR(i);
1782        for (j=0; j < BTA_HL_NUM_MCLS ; j++)
1783        {
1784            if (p_acb->mcb[j].in_use)
1785                BTIF_TRACE_DEBUG3("btif_hl_find_mcl_idx_using_handle:app_idx=%d,"
1786                "mcl_idx =%d mcl_handle=%d",i,j,p_acb->mcb[j].mcl_handle);
1787            if (p_acb->mcb[j].in_use &&
1788                (p_acb->mcb[j].mcl_handle == mcl_handle))
1789            {
1790                found = TRUE;
1791                *p_app_idx = i;
1792                *p_mcl_idx = j;
1793                break;
1794            }
1795        }
1796    }
1797    BTIF_TRACE_DEBUG4("%s found=%d app_idx=%d mcl_idx=%d",__FUNCTION__,
1798                      found, i, j);
1799    return found;
1800}
1801
1802/*******************************************************************************
1803**
1804** Function      btif_hl_find_mdl_idx_using_mdl_id
1805**
1806** Description  Find the mdl index using mdl_id
1807**
1808** Returns      BOOLEAN
1809**
1810*******************************************************************************/
1811BOOLEAN btif_hl_find_mcl_idx_using_mdl_id( UINT8 mdl_id,UINT8 mcl_handle,
1812                                           UINT8 *p_app_idx, UINT8 *p_mcl_idx){
1813    btif_hl_app_cb_t  *p_acb;
1814    btif_hl_mcl_cb_t  *p_mcb;
1815    BOOLEAN         found=FALSE;
1816    UINT8 i,j,x;
1817
1818    for (i=0; i<BTA_HL_NUM_APPS; i++)
1819    {
1820        p_acb =BTIF_HL_GET_APP_CB_PTR(i);
1821        for (j=0; j < BTA_HL_NUM_MCLS ; j++)
1822        {
1823            if (p_acb->mcb[j].in_use &&
1824                (p_acb->mcb[j].mcl_handle == mcl_handle))
1825            {
1826                    p_mcb = &p_acb->mcb[j];
1827                    BTIF_TRACE_DEBUG1("btif_hl_find_mcl_idx_using_mdl_id: mcl handle found j =%d",j);
1828                    for (x=0; x < BTA_HL_NUM_MDLS_PER_MCL ; x ++)
1829                    {
1830                        if (p_mcb->mdl[x].in_use && p_mcb->mdl[x].mdl_id == mdl_id)
1831                        {
1832                            BTIF_TRACE_DEBUG1("btif_hl_find_mcl_idx_using_mdl_id:found x =%d",x);
1833                            found = TRUE;
1834                            *p_app_idx = i;
1835                            *p_mcl_idx = j;
1836                            break;
1837                        }
1838                    }
1839            }
1840        }
1841    }
1842    BTIF_TRACE_DEBUG4("%s found=%d app_idx=%d mcl_idx=%d",__FUNCTION__,
1843                      found, i, j);
1844    return found;
1845}
1846
1847/*******************************************************************************
1848**
1849** Function      btif_hl_find_mcl_idx_using_deleted_mdl_id
1850**
1851** Description  Find the app index deleted_mdl_id
1852**
1853** Returns      BOOLEAN
1854**
1855*******************************************************************************/
1856BOOLEAN btif_hl_find_app_idx_using_deleted_mdl_id( UINT8 mdl_id,
1857                                           UINT8 *p_app_idx){
1858    btif_hl_app_cb_t  *p_acb;
1859    BOOLEAN         found=FALSE;
1860    UINT8 i,j;
1861
1862    for (i=0; i<BTA_HL_NUM_APPS; i++)
1863    {
1864        p_acb =BTIF_HL_GET_APP_CB_PTR(i);
1865        if (p_acb->delete_mdl.active)
1866                BTIF_TRACE_DEBUG3("btif_hl_find_app_idx_using_deleted_mdl_id: app_idx=%d,"
1867                    "mcl_idx =%d mcl_handle=%d",i,j,p_acb->mcb[j].mcl_handle);
1868            if (p_acb->delete_mdl.active &&
1869                (p_acb->delete_mdl.mdl_id == mdl_id))
1870            {
1871                found = TRUE;
1872                *p_app_idx = i;
1873                break;
1874            }
1875    }
1876    BTIF_TRACE_DEBUG3("%s found=%d app_idx=%d",__FUNCTION__,
1877                      found, i);
1878    return found;
1879}
1880
1881/*******************************************************************************
1882**
1883** Function      btif_hl_stop_timer_using_handle
1884**
1885** Description  clean control channel cb using handle
1886**
1887** Returns      void
1888**
1889*******************************************************************************/
1890static void btif_hl_stop_timer_using_handle( tBTA_HL_MCL_HANDLE mcl_handle){
1891    btif_hl_app_cb_t  *p_acb;
1892    BOOLEAN         found=FALSE;
1893    UINT8 i,j;
1894
1895    for (i=0; i<BTA_HL_NUM_APPS; i++)
1896    {
1897        p_acb =BTIF_HL_GET_APP_CB_PTR(i);
1898        for (j=0; j < BTA_HL_NUM_MCLS ; j++)
1899        {
1900            if (p_acb->mcb[j].in_use &&
1901                (p_acb->mcb[j].mcl_handle == mcl_handle))
1902            {
1903                btif_hl_stop_cch_timer(i, j);
1904            }
1905        }
1906    }
1907}
1908
1909/*******************************************************************************
1910**
1911** Function      btif_hl_find_mcl_idx_using_app_idx
1912**
1913** Description  Find the MCL index using handle
1914**
1915** Returns      BOOLEAN
1916**
1917*******************************************************************************/
1918BOOLEAN btif_hl_find_mcl_idx_using_app_idx( tBTA_HL_MCL_HANDLE mcl_handle,
1919                                           UINT8 p_app_idx, UINT8 *p_mcl_idx){
1920    btif_hl_app_cb_t  *p_acb;
1921    BOOLEAN         found=FALSE;
1922    UINT8 i,j;
1923
1924    p_acb =BTIF_HL_GET_APP_CB_PTR(p_app_idx);
1925    for (j=0; j < BTA_HL_NUM_MCLS ; j++)
1926    {
1927        if (p_acb->mcb[j].in_use &&
1928            (p_acb->mcb[j].mcl_handle == mcl_handle))
1929        {
1930            found = TRUE;
1931            *p_mcl_idx = j;
1932            break;
1933        }
1934    }
1935    BTIF_TRACE_DEBUG3("%s found=%dmcl_idx=%d",__FUNCTION__,
1936                      found, j);
1937    return found;
1938}
1939
1940/*******************************************************************************
1941**
1942** Function      btif_hl_clean_mdls_using_app_idx
1943**
1944** Description  clean dch cpntrol bloack using app_idx
1945**
1946** Returns      void
1947**
1948*******************************************************************************/
1949void btif_hl_clean_mdls_using_app_idx( UINT8 app_idx){
1950    btif_hl_app_cb_t  *p_acb;
1951    btif_hl_mcl_cb_t  *p_mcb;
1952    btif_hl_mdl_cb_t  *p_dcb;
1953    UINT8 i,j,x,y;
1954    bt_bdaddr_t     bd_addr;
1955
1956        p_acb =BTIF_HL_GET_APP_CB_PTR(app_idx);
1957        for (j=0; j < BTA_HL_NUM_MCLS ; j++)
1958        {
1959            if (p_acb->mcb[j].in_use)
1960            {
1961                    p_mcb = &p_acb->mcb[j];
1962                    BTIF_TRACE_DEBUG1("btif_hl_find_mcl_idx_using_mdl_id: mcl handle found j =%d",j);
1963                    for (x=0; x < BTA_HL_NUM_MDLS_PER_MCL ; x ++)
1964                    {
1965                        if (p_mcb->mdl[x].in_use)
1966                        {
1967                            p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, j,x);
1968                            btif_hl_release_socket(app_idx,j,x);
1969                            for (y=0; y<6; y++)
1970                            {
1971                                bd_addr.address[y] = p_mcb->bd_addr[y];
1972                            }
1973                            BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb,  p_acb->app_id,
1974                                               &bd_addr, p_dcb->local_mdep_cfg_idx,
1975                                               p_dcb->channel_id, BTHL_CONN_STATE_DISCONNECTED, 0 );
1976                            btif_hl_clean_mdl_cb(p_dcb);
1977                            if (!btif_hl_num_dchs_in_use(p_mcb->mcl_handle))
1978                                    BTA_HlCchClose(p_mcb->mcl_handle);
1979                            BTIF_TRACE_DEBUG1("remote DCH close success mdl_idx=%d", x);
1980                        }
1981                    }
1982            }
1983        }
1984}
1985
1986/*******************************************************************************
1987**
1988** Function      btif_hl_find_app_idx
1989**
1990** Description  Find the application index using application ID
1991**
1992** Returns      BOOLEAN
1993**
1994*******************************************************************************/
1995BOOLEAN btif_hl_find_app_idx(UINT8 app_id, UINT8 *p_app_idx){
1996    BOOLEAN found=FALSE;
1997    UINT8 i;
1998
1999    for (i=0; i < BTA_HL_NUM_APPS ; i ++)
2000    {
2001
2002        if (btif_hl_cb.acb[i].in_use &&
2003            (btif_hl_cb.acb[i].app_id == app_id))
2004        {
2005            found = TRUE;
2006            *p_app_idx = i;
2007            break;
2008        }
2009    }
2010    BTIF_TRACE_DEBUG3("%s found=%d app_idx=%d", __FUNCTION__, found, i );
2011
2012    return found;
2013}
2014
2015/*******************************************************************************
2016**
2017** Function      btif_hl_find_app_idx
2018**
2019** Description  Find the application index using application ID
2020**
2021** Returns      BOOLEAN
2022**
2023*******************************************************************************/
2024BOOLEAN btif_hl_find_app_idx_using_mdepId(UINT8 mdep_id, UINT8 *p_app_idx){
2025    BOOLEAN found=FALSE;
2026    UINT8 i;
2027
2028    for (i=0; i < BTA_HL_NUM_APPS ; i ++)
2029    {
2030        BTIF_TRACE_DEBUG1("btif_hl_find_app_idx_using_mdepId: MDEP-ID = %d",
2031                btif_hl_cb.acb[i].sup_feature.mdep[0].mdep_id);
2032        if (btif_hl_cb.acb[i].in_use &&
2033            (btif_hl_cb.acb[i].sup_feature.mdep[0].mdep_id == mdep_id))
2034        {
2035            found = TRUE;
2036            *p_app_idx = i;
2037            break;
2038        }
2039    }
2040    BTIF_TRACE_DEBUG3("%s found=%d app_idx=%d", __FUNCTION__, found, i );
2041
2042    return found;
2043}
2044
2045/*******************************************************************************
2046**
2047** Function      btif_hl_find_avail_mdl_idx
2048**
2049** Description  Find a not in-use MDL index
2050**
2051** Returns      BOOLEAN
2052**
2053*******************************************************************************/
2054BOOLEAN btif_hl_find_avail_mdl_idx(UINT8 app_idx, UINT8 mcl_idx,
2055                                   UINT8 *p_mdl_idx){
2056    btif_hl_mcl_cb_t      *p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2057    BOOLEAN found=FALSE;
2058    UINT8 i;
2059
2060    for (i=0; i < BTA_HL_NUM_MDLS_PER_MCL ; i ++)
2061    {
2062        if (!p_mcb->mdl[i].in_use)
2063        {
2064            btif_hl_clean_mdl_cb(&p_mcb->mdl[i]);
2065            found = TRUE;
2066            *p_mdl_idx = i;
2067            break;
2068        }
2069    }
2070
2071    BTIF_TRACE_DEBUG3("%s found=%d idx=%d",__FUNCTION__, found, i);
2072    return found;
2073}
2074
2075/*******************************************************************************
2076**
2077** Function      btif_hl_find_avail_mcl_idx
2078**
2079** Description  Find a not in-use MDL index
2080**
2081** Returns      BOOLEAN
2082**
2083*******************************************************************************/
2084BOOLEAN btif_hl_find_avail_mcl_idx(UINT8 app_idx, UINT8 *p_mcl_idx){
2085    BOOLEAN found=FALSE;
2086    UINT8 i;
2087
2088    for (i=0; i < BTA_HL_NUM_MCLS ; i ++)
2089    {
2090        if (!btif_hl_cb.acb[app_idx].mcb[i].in_use)
2091        {
2092            found = TRUE;
2093            *p_mcl_idx = i;
2094            break;
2095        }
2096    }
2097    BTIF_TRACE_DEBUG3("%s found=%d mcl_idx=%d", __FUNCTION__, found, i);
2098    return found;
2099}
2100
2101/*******************************************************************************
2102**
2103** Function      btif_hl_find_avail_app_idx
2104**
2105** Description  Find a not in-use APP index
2106**
2107** Returns      BOOLEAN
2108**
2109*******************************************************************************/
2110static BOOLEAN btif_hl_find_avail_app_idx(UINT8 *p_idx){
2111    BOOLEAN found = FALSE;
2112    UINT8 i;
2113
2114    for (i=0; i < BTA_HL_NUM_APPS ; i ++)
2115    {
2116        if (!btif_hl_cb.acb[i].in_use)
2117        {
2118            found = TRUE;
2119            *p_idx = i;
2120            break;
2121        }
2122    }
2123
2124    BTIF_TRACE_DEBUG3("%s found=%d app_idx=%d", __FUNCTION__, found, i);
2125    return found;
2126}
2127
2128
2129/*******************************************************************************
2130**
2131** Function         btif_hl_proc_dereg_cfm
2132**
2133** Description      Process the de-registration confirmation
2134**
2135** Returns          Nothing
2136**
2137*******************************************************************************/
2138static void btif_hl_proc_dereg_cfm(tBTA_HL *p_data)
2139
2140{
2141    btif_hl_app_cb_t        *p_acb;
2142    UINT8                   app_idx;
2143    int                     app_id = 0;
2144    bthl_app_reg_state_t    state = BTHL_APP_REG_STATE_DEREG_SUCCESS;
2145    bt_status_t             status            = BT_STATUS_SUCCESS;
2146
2147    BTIF_TRACE_DEBUG3("%s de-reg status=%d app_handle=%d", __FUNCTION__,
2148                p_data->dereg_cfm.status, p_data->dereg_cfm.app_handle);
2149
2150    if (btif_hl_find_app_idx_using_app_id(p_data->dereg_cfm.app_id, &app_idx))
2151    {
2152        p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
2153        app_id = (int) p_acb->app_id;
2154        if (p_data->dereg_cfm.status == BTA_HL_STATUS_OK)
2155        {
2156            btif_hl_clean_mdls_using_app_idx(app_idx);
2157            memset(p_acb, 0,sizeof(btif_hl_app_cb_t));
2158        }
2159        else
2160            state = BTHL_APP_REG_STATE_DEREG_FAILED;
2161
2162        BTIF_TRACE_DEBUG2("call reg state callback app_id=%d state=%d", app_id, state);
2163        BTIF_HL_CALL_CBACK(bt_hl_callbacks, app_reg_state_cb, app_id, state );
2164
2165        if (btif_hl_is_no_active_app())
2166        {
2167            btif_hl_disable();
2168        }
2169    }
2170}
2171
2172/*******************************************************************************
2173**
2174** Function         btif_hl_proc_reg_cfm
2175**
2176** Description      Process the registration confirmation
2177**
2178** Returns          Nothing
2179**
2180*******************************************************************************/
2181static void btif_hl_proc_reg_cfm(tBTA_HL *p_data){
2182    btif_hl_app_cb_t       *p_acb;
2183    UINT8                  app_idx;
2184    bthl_app_reg_state_t   state = BTHL_APP_REG_STATE_REG_SUCCESS;
2185    bt_status_t            bt_status;
2186
2187    BTIF_TRACE_DEBUG3("%s reg status=%d app_handle=%d", __FUNCTION__, p_data->reg_cfm.status, p_data->reg_cfm.app_handle);
2188
2189    if (btif_hl_find_app_idx(p_data->reg_cfm.app_id, &app_idx))
2190    {
2191        p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
2192        if (p_data->reg_cfm.status == BTA_HL_STATUS_OK)
2193        {
2194            p_acb->app_handle = p_data->reg_cfm.app_handle;
2195        }
2196        else
2197        {
2198            btif_hl_free_app_idx(app_idx);
2199            reg_counter--;
2200            state = BTHL_APP_REG_STATE_REG_FAILED;
2201        }
2202
2203        BTIF_TRACE_DEBUG3("%s call reg state callback app_id=%d reg state=%d", __FUNCTION__,  p_data->reg_cfm.app_id, state);
2204        BTIF_HL_CALL_CBACK(bt_hl_callbacks, app_reg_state_cb, ((int) p_data->reg_cfm.app_id), state );
2205    }
2206}
2207
2208/*******************************************************************************
2209**
2210** Function         btif_hl_proc_sdp_info_ind
2211**
2212** Description      Process the SDP info indication
2213**
2214** Returns          Nothing
2215**
2216*******************************************************************************/
2217static void btif_hl_proc_sdp_info_ind(tBTA_HL *p_data)
2218
2219{
2220    btif_hl_app_cb_t         *p_acb;
2221    UINT8                   app_idx;
2222
2223    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
2224    if (btif_hl_find_app_idx_using_handle(p_data->sdp_info_ind.app_handle, &app_idx))
2225    {
2226        p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
2227        memcpy(&p_acb->sdp_info_ind, &p_data->sdp_info_ind, sizeof(tBTA_HL_SDP_INFO_IND));
2228    }
2229}
2230/*******************************************************************************
2231**
2232** Function btif_hl_set_chan_cb_state
2233**
2234** Description set the channel callback state
2235**
2236** Returns void
2237**
2238*******************************************************************************/
2239void btif_hl_set_chan_cb_state(UINT8 app_idx, UINT8 mcl_idx, btif_hl_chan_cb_state_t state){
2240    btif_hl_pending_chan_cb_t   *p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
2241    btif_hl_chan_cb_state_t cur_state = p_pcb->cb_state;
2242
2243    if (cur_state != state)
2244    {
2245        p_pcb->cb_state = state;
2246        BTIF_TRACE_DEBUG3("%s state %d--->%d",__FUNCTION__, cur_state, state);
2247    }
2248
2249
2250}
2251/*******************************************************************************
2252**
2253** Function btif_hl_send_destroyed_cb
2254**
2255** Description send the channel destroyed callback
2256**
2257** Returns void
2258**
2259*******************************************************************************/
2260void btif_hl_send_destroyed_cb(btif_hl_app_cb_t        *p_acb ){
2261    bt_bdaddr_t     bd_addr;
2262    int             app_id = (int) btif_hl_get_app_id(p_acb->delete_mdl.channel_id);
2263
2264    btif_hl_copy_bda(&bd_addr, p_acb->delete_mdl.bd_addr);
2265    BTIF_TRACE_DEBUG1("%s",__FUNCTION__);
2266    BTIF_TRACE_DEBUG4("call channel state callback channel_id=0x%08x mdep_cfg_idx=%d, state=%d fd=%d",p_acb->delete_mdl.channel_id,
2267                      p_acb->delete_mdl.mdep_cfg_idx, BTHL_CONN_STATE_DESTROYED, 0);
2268    btif_hl_display_bt_bda(&bd_addr);
2269
2270    BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb,  app_id,
2271                       &bd_addr, p_acb->delete_mdl.mdep_cfg_idx,
2272                       p_acb->delete_mdl.channel_id, BTHL_CONN_STATE_DESTROYED, 0 );
2273}
2274/*******************************************************************************
2275**
2276** Function btif_hl_send_disconnecting_cb
2277**
2278** Description send a channel disconnecting callback
2279**
2280** Returns void
2281**
2282*******************************************************************************/
2283void btif_hl_send_disconnecting_cb(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx){
2284    btif_hl_mdl_cb_t        *p_dcb = BTIF_HL_GET_MDL_CB_PTR( app_idx,  mcl_idx, mdl_idx);
2285    btif_hl_soc_cb_t        *p_scb = p_dcb->p_scb;
2286    bt_bdaddr_t             bd_addr;
2287    int                     app_id = (int) btif_hl_get_app_id(p_scb->channel_id);
2288
2289    btif_hl_copy_bda(&bd_addr, p_scb->bd_addr);
2290
2291    BTIF_TRACE_DEBUG1("%s",__FUNCTION__);
2292    BTIF_TRACE_DEBUG4("call channel state callback  channel_id=0x%08x mdep_cfg_idx=%d, state=%d fd=%d",p_scb->channel_id,
2293                      p_scb->mdep_cfg_idx, BTHL_CONN_STATE_DISCONNECTING, p_scb->socket_id[0]);
2294    btif_hl_display_bt_bda(&bd_addr);
2295    BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb,  app_id,
2296                       &bd_addr, p_scb->mdep_cfg_idx,
2297                       p_scb->channel_id, BTHL_CONN_STATE_DISCONNECTING, p_scb->socket_id[0] );
2298}
2299/*******************************************************************************
2300**
2301** Function btif_hl_send_setup_connecting_cb
2302**
2303** Description send a channel connecting callback
2304**
2305** Returns void
2306**
2307*******************************************************************************/
2308void btif_hl_send_setup_connecting_cb(UINT8 app_idx, UINT8 mcl_idx){
2309    btif_hl_pending_chan_cb_t   *p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
2310    bt_bdaddr_t                 bd_addr;
2311    int                         app_id = (int) btif_hl_get_app_id(p_pcb->channel_id);
2312
2313    btif_hl_copy_bda(&bd_addr, p_pcb->bd_addr);
2314
2315    if (p_pcb->in_use && p_pcb->cb_state == BTIF_HL_CHAN_CB_STATE_CONNECTING_PENDING)
2316    {
2317        BTIF_TRACE_DEBUG1("%s",__FUNCTION__);
2318        BTIF_TRACE_DEBUG4("call channel state callback  channel_id=0x%08x mdep_cfg_idx=%d state=%d fd=%d",p_pcb->channel_id,
2319                          p_pcb->mdep_cfg_idx, BTHL_CONN_STATE_CONNECTING, 0);
2320        btif_hl_display_bt_bda(&bd_addr);
2321
2322        BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id,
2323                           &bd_addr, p_pcb->mdep_cfg_idx,
2324                           p_pcb->channel_id, BTHL_CONN_STATE_CONNECTING, 0 );
2325        btif_hl_set_chan_cb_state(app_idx, mcl_idx, BTIF_HL_CHAN_CB_STATE_CONNECTED_PENDING);
2326    }
2327}
2328/*******************************************************************************
2329**
2330** Function btif_hl_send_setup_disconnected_cb
2331**
2332** Description send a channel disconnected callback
2333**
2334** Returns void
2335**
2336*******************************************************************************/
2337void btif_hl_send_setup_disconnected_cb(UINT8 app_idx, UINT8 mcl_idx){
2338    btif_hl_pending_chan_cb_t   *p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
2339    bt_bdaddr_t                 bd_addr;
2340    int                         app_id = (int) btif_hl_get_app_id(p_pcb->channel_id);
2341
2342    btif_hl_copy_bda(&bd_addr, p_pcb->bd_addr);
2343
2344    BTIF_TRACE_DEBUG2("%s p_pcb->in_use=%d",__FUNCTION__, p_pcb->in_use);
2345    if (p_pcb->in_use)
2346    {
2347        BTIF_TRACE_DEBUG1("%p_pcb->cb_state=%d",p_pcb->cb_state);
2348        if (p_pcb->cb_state == BTIF_HL_CHAN_CB_STATE_CONNECTING_PENDING)
2349        {
2350            BTIF_TRACE_DEBUG4("call channel state callback  channel_id=0x%08x mdep_cfg_idx=%d state=%d fd=%d",p_pcb->channel_id,
2351                              p_pcb->mdep_cfg_idx, BTHL_CONN_STATE_CONNECTING, 0);
2352            btif_hl_display_bt_bda(&bd_addr);
2353            BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id,
2354                               &bd_addr, p_pcb->mdep_cfg_idx,
2355                               p_pcb->channel_id, BTHL_CONN_STATE_CONNECTING, 0 );
2356
2357            BTIF_TRACE_DEBUG4("call channel state callback  channel_id=0x%08x mdep_cfg_idx=%d state=%d fd=%d",p_pcb->channel_id,
2358                              p_pcb->mdep_cfg_idx, BTHL_CONN_STATE_DISCONNECTED, 0);
2359            btif_hl_display_bt_bda(&bd_addr);
2360            BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id,
2361                               &bd_addr, p_pcb->mdep_cfg_idx,
2362                               p_pcb->channel_id, BTHL_CONN_STATE_DISCONNECTED, 0 );
2363        }
2364        else if (p_pcb->cb_state == BTIF_HL_CHAN_CB_STATE_CONNECTED_PENDING)
2365        {
2366            BTIF_TRACE_DEBUG4("call channel state callback  channel_id=0x%08x mdep_cfg_idx=%d state=%d fd=%d",p_pcb->channel_id,
2367                              p_pcb->mdep_cfg_idx, BTHL_CONN_STATE_DISCONNECTED, 0);
2368            btif_hl_display_bt_bda(&bd_addr);
2369            BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb,  app_id,
2370                               &bd_addr, p_pcb->mdep_cfg_idx,
2371                               p_pcb->channel_id, BTHL_CONN_STATE_DISCONNECTED, 0 );
2372        }
2373        btif_hl_clean_pcb(p_pcb);
2374    }
2375}
2376/*******************************************************************************
2377**
2378** Function         btif_hl_proc_sdp_query_cfm
2379**
2380** Description      Process the SDP query confirmation
2381**
2382** Returns          Nothing
2383**
2384*******************************************************************************/
2385static BOOLEAN btif_hl_proc_sdp_query_cfm(tBTA_HL *p_data){
2386    btif_hl_app_cb_t                *p_acb;
2387    btif_hl_mcl_cb_t                *p_mcb;
2388    tBTA_HL_SDP                     *p_sdp;
2389    tBTA_HL_CCH_OPEN_PARAM          open_param;
2390    UINT8                           app_idx, mcl_idx, sdp_idx = 0;
2391    UINT8                           num_recs, i, num_mdeps, j;
2392    btif_hl_cch_op_t                old_cch_oper;
2393    BOOLEAN                         status =FALSE;
2394    btif_hl_pending_chan_cb_t     *p_pcb;
2395
2396    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
2397
2398    p_sdp = p_data->sdp_query_cfm.p_sdp;
2399    num_recs = p_sdp->num_recs;
2400
2401    BTIF_TRACE_DEBUG1("num of SDP records=%d",num_recs);
2402    for (i=0; i<num_recs; i++)
2403    {
2404        BTIF_TRACE_DEBUG3("rec_idx=%d ctrl_psm=0x%x data_psm=0x%x",
2405                          (i+1),p_sdp->sdp_rec[i].ctrl_psm, p_sdp->sdp_rec[i].data_psm);
2406        BTIF_TRACE_DEBUG1("MCAP supported procedures=0x%x",p_sdp->sdp_rec[i].mcap_sup_proc);
2407        num_mdeps = p_sdp->sdp_rec[i].num_mdeps;
2408        BTIF_TRACE_DEBUG1("num of mdeps =%d",num_mdeps);
2409        for (j=0; j< num_mdeps; j++)
2410        {
2411            BTIF_TRACE_DEBUG4("mdep_idx=%d mdep_id=0x%x data_type=0x%x mdep_role=0x%x",
2412                              (j+1),
2413                              p_sdp->sdp_rec[i].mdep_cfg[j].mdep_id,
2414                              p_sdp->sdp_rec[i].mdep_cfg[j].data_type,
2415                              p_sdp->sdp_rec[i].mdep_cfg[j].mdep_role );
2416        }
2417    }
2418
2419        if (btif_hl_find_app_idx_using_app_id(p_data->sdp_query_cfm.app_id, &app_idx))
2420        {
2421            p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
2422
2423            if (btif_hl_find_mcl_idx(app_idx, p_data->sdp_query_cfm.bd_addr, &mcl_idx))
2424            {
2425                p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2426                if (p_mcb->cch_oper != BTIF_HL_CCH_OP_NONE)
2427                {
2428                    memcpy(&p_mcb->sdp, p_sdp, sizeof(tBTA_HL_SDP));
2429                    old_cch_oper = p_mcb->cch_oper;
2430                    p_mcb->cch_oper = BTIF_HL_CCH_OP_NONE;
2431
2432                    switch (old_cch_oper)
2433                    {
2434                        case BTIF_HL_CCH_OP_MDEP_FILTERING:
2435                            status = btif_hl_find_sdp_idx_using_mdep_filter(app_idx,
2436                                                                    mcl_idx, &sdp_idx);
2437                            break;
2438                        default:
2439                            break;
2440                    }
2441
2442                    if (status)
2443                    {
2444                        p_mcb->sdp_idx       = sdp_idx;
2445                        p_mcb->valid_sdp_idx = TRUE;
2446                        p_mcb->ctrl_psm      = p_mcb->sdp.sdp_rec[sdp_idx].ctrl_psm;
2447
2448                        switch (old_cch_oper)
2449                        {
2450                            case BTIF_HL_CCH_OP_MDEP_FILTERING:
2451                                p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
2452                                if (p_pcb->in_use)
2453                                {
2454                                    if (!p_pcb->abort_pending)
2455                                    {
2456                                        switch (p_pcb->op)
2457                                        {
2458                                            case BTIF_HL_PEND_DCH_OP_OPEN:
2459                                                btif_hl_send_setup_connecting_cb(app_idx, mcl_idx);
2460                                                break;
2461                                            case BTIF_HL_PEND_DCH_OP_DELETE_MDL:
2462                                            default:
2463                                                break;
2464                                        }
2465                                        open_param.ctrl_psm = p_mcb->ctrl_psm;
2466                                        bdcpy(open_param.bd_addr, p_mcb->bd_addr);
2467                                        open_param.sec_mask =
2468                                                (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
2469                                        BTA_HlCchOpen(p_acb->app_id,p_acb->app_handle, &open_param);
2470                                    }
2471                                    else
2472                                    {
2473                                        BTIF_TRACE_DEBUG0("channel abort pending");
2474                                    }
2475                                }
2476                                break;
2477
2478                            case BTIF_HL_CCH_OP_DCH_OPEN:
2479                                status = btif_hl_proc_pending_op(app_idx,mcl_idx);
2480                                break;
2481
2482                            default:
2483                                BTIF_TRACE_ERROR1("Invalid CCH oper %d", old_cch_oper);
2484                                break;
2485                        }
2486                    }
2487                    else
2488                    {
2489                        BTIF_TRACE_ERROR0("Can not find SDP idx discard CCH Open request");
2490                    }
2491                }
2492            }
2493        }
2494    return status;
2495}
2496
2497
2498/*******************************************************************************
2499**
2500** Function         btif_hl_proc_cch_open_ind
2501**
2502** Description      Process the CCH open indication
2503**
2504** Returns          Nothing
2505**
2506*******************************************************************************/
2507static void btif_hl_proc_cch_open_ind(tBTA_HL *p_data)
2508
2509{
2510    btif_hl_mcl_cb_t         *p_mcb;
2511    UINT8                   app_idx, mcl_idx;
2512    int                     i;
2513
2514    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
2515    for(i=0; i<BTA_HL_NUM_APPS; i++)
2516    {
2517        if (btif_hl_cb.acb[i].in_use)
2518        {
2519            if (!btif_hl_find_mcl_idx(i, p_data->cch_open_ind.bd_addr, &mcl_idx))
2520            {
2521                if (btif_hl_find_avail_mcl_idx(i, &mcl_idx))
2522                {
2523                    p_mcb = BTIF_HL_GET_MCL_CB_PTR(i, mcl_idx);
2524                    memset(p_mcb, 0, sizeof(btif_hl_mcl_cb_t));
2525                    p_mcb->in_use = TRUE;
2526                    p_mcb->is_connected = TRUE;
2527                    p_mcb->mcl_handle = p_data->cch_open_ind.mcl_handle;
2528                    bdcpy(p_mcb->bd_addr, p_data->cch_open_ind.bd_addr);
2529                    btif_hl_start_cch_timer(i, mcl_idx);
2530                }
2531            }
2532            else
2533            {
2534                BTIF_TRACE_ERROR0("The MCL already exist for cch_open_ind");
2535            }
2536        }
2537    }
2538}
2539
2540/*******************************************************************************
2541**
2542** Function         btif_hl_proc_pending_op
2543**
2544** Description      Process the pending dch operation.
2545**
2546** Returns          Nothing
2547**
2548*******************************************************************************/
2549BOOLEAN btif_hl_proc_pending_op(UINT8 app_idx, UINT8 mcl_idx)
2550
2551{
2552
2553    btif_hl_app_cb_t            *p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
2554    btif_hl_mcl_cb_t            *p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2555    btif_hl_pending_chan_cb_t   *p_pcb;
2556    BOOLEAN                     status = FALSE;
2557    tBTA_HL_DCH_OPEN_PARAM      dch_open;
2558    tBTA_HL_MDL_ID              mdl_id;
2559    tBTA_HL_DCH_RECONNECT_PARAM reconnect_param;
2560
2561    p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
2562    if (p_pcb->in_use)
2563    {
2564        switch (p_pcb->op)
2565        {
2566            case BTIF_HL_PEND_DCH_OP_OPEN:
2567                if (!p_pcb->abort_pending)
2568                {
2569                    BTIF_TRACE_DEBUG0("op BTIF_HL_PEND_DCH_OP_OPEN");
2570                    dch_open.ctrl_psm = p_mcb->ctrl_psm;
2571                    dch_open.local_mdep_id = p_acb->sup_feature.mdep[p_pcb->mdep_cfg_idx].mdep_id;
2572                    if (btif_hl_find_peer_mdep_id(p_acb->app_id, p_mcb->bd_addr,
2573                                                  p_acb->sup_feature.mdep[p_pcb->mdep_cfg_idx].mdep_cfg.mdep_role,
2574                                                  p_acb->sup_feature.mdep[p_pcb->mdep_cfg_idx].mdep_cfg.data_cfg[0].data_type, &dch_open.peer_mdep_id ))
2575                    {
2576                        dch_open.local_cfg = p_acb->channel_type[p_pcb->mdep_cfg_idx];
2577                        if ((p_acb->sup_feature.mdep[p_pcb->mdep_cfg_idx].mdep_cfg.mdep_role == BTA_HL_MDEP_ROLE_SOURCE)
2578                            && !btif_hl_is_the_first_reliable_existed(app_idx, mcl_idx))
2579                        {
2580                            dch_open.local_cfg = BTA_HL_DCH_CFG_RELIABLE;
2581                        }
2582                        dch_open.sec_mask = (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
2583                        BTIF_TRACE_DEBUG1("dch_open.local_cfg=%d  ", dch_open.local_cfg);
2584                        btif_hl_send_setup_connecting_cb(app_idx,mcl_idx);
2585
2586                        if (!btif_hl_is_reconnect_possible(app_idx, mcl_idx, p_pcb->mdep_cfg_idx, &dch_open, &mdl_id ))
2587                        {
2588                            BTIF_TRACE_DEBUG1("Issue DCH open, mcl_handle=%d",p_mcb->mcl_handle);
2589                            BTA_HlDchOpen(p_mcb->mcl_handle, &dch_open);
2590                        }
2591                        else
2592                        {
2593                            reconnect_param.ctrl_psm = p_mcb->ctrl_psm;
2594                            reconnect_param.mdl_id = mdl_id;;
2595                            BTIF_TRACE_DEBUG2("Issue Reconnect ctrl_psm=0x%x mdl_id=0x%x",reconnect_param.ctrl_psm, reconnect_param.mdl_id);
2596                            BTA_HlDchReconnect(p_mcb->mcl_handle, &reconnect_param);
2597                        }
2598                        status = TRUE;
2599                    }
2600                }
2601                else
2602                {
2603                    btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx);
2604                    status = TRUE;
2605                }
2606                break;
2607            case BTIF_HL_PEND_DCH_OP_DELETE_MDL:
2608                BTA_HlDeleteMdl(p_mcb->mcl_handle, p_acb->delete_mdl.mdl_id);
2609                status = TRUE;
2610                break;
2611
2612            default:
2613                break;
2614        }
2615    }
2616    return status;
2617}
2618
2619/*******************************************************************************
2620**
2621** Function         btif_hl_proc_cch_open_cfm
2622**
2623** Description      Process the CCH open confirmation
2624**
2625** Returns          Nothing
2626**
2627*******************************************************************************/
2628static BOOLEAN btif_hl_proc_cch_open_cfm(tBTA_HL *p_data)
2629
2630{
2631    btif_hl_app_cb_t         *p_acb;
2632    btif_hl_mcl_cb_t         *p_mcb;
2633    UINT8                    app_idx, mcl_idx;
2634    BOOLEAN                  status = FALSE;
2635    tBTA_HL_DCH_OPEN_PARAM   dch_open;
2636
2637
2638    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
2639
2640    if (btif_hl_find_app_idx_using_app_id(p_data->cch_open_cfm.app_id, &app_idx))
2641    {
2642        BTIF_TRACE_DEBUG1("app_idx=%d", app_idx);
2643        if (btif_hl_find_mcl_idx(app_idx, p_data->cch_open_cfm.bd_addr, &mcl_idx))
2644        {
2645            p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
2646
2647            p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2648            BTIF_TRACE_DEBUG2("mcl_idx=%d, mcl_handle=%d", mcl_idx,p_data->cch_open_cfm.mcl_handle);
2649            p_mcb->mcl_handle = p_data->cch_open_cfm.mcl_handle;
2650            p_mcb->is_connected = TRUE;
2651            status = btif_hl_proc_pending_op(app_idx, mcl_idx);
2652            if (status)
2653                btif_hl_start_cch_timer(app_idx, mcl_idx);
2654        }
2655    }
2656
2657    return status;
2658}
2659
2660/*******************************************************************************
2661**
2662** Function      btif_hl_clean_mcb_using_handle
2663**
2664** Description  clean control channel cb using handle
2665**
2666** Returns      void
2667**
2668*******************************************************************************/
2669static void btif_hl_clean_mcb_using_handle( tBTA_HL_MCL_HANDLE mcl_handle){
2670    btif_hl_app_cb_t  *p_acb;
2671    UINT8 i,j;
2672
2673    for (i=0; i<BTA_HL_NUM_APPS; i++)
2674    {
2675        p_acb =BTIF_HL_GET_APP_CB_PTR(i);
2676        for (j=0; j < BTA_HL_NUM_MCLS ; j++)
2677        {
2678            if (p_acb->mcb[j].in_use)
2679                BTIF_TRACE_DEBUG3("btif_hl_find_mcl_idx_using_handle: app_idx=%d,"
2680                    "mcl_idx =%d mcl_handle=%d",i,j,p_acb->mcb[j].mcl_handle);
2681            if (p_acb->mcb[j].in_use &&
2682                (p_acb->mcb[j].mcl_handle == mcl_handle))
2683            {
2684                btif_hl_stop_cch_timer(i, j);
2685                btif_hl_release_mcl_sockets(i, j);
2686                btif_hl_send_setup_disconnected_cb(i, j);
2687                btif_hl_clean_mcl_cb(i, j);
2688            }
2689        }
2690    }
2691}
2692
2693/*******************************************************************************
2694**
2695** Function         btif_hl_proc_cch_close_ind
2696**
2697** Description      Process the CCH close indication
2698**
2699** Returns          Nothing
2700**
2701*******************************************************************************/
2702static void btif_hl_proc_cch_close_ind(tBTA_HL *p_data)
2703
2704{
2705    UINT8                   app_idx, mcl_idx;
2706    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
2707
2708    btif_hl_clean_mcb_using_handle(p_data->cch_close_ind.mcl_handle);
2709}
2710
2711
2712/*******************************************************************************
2713**
2714** Function         btif_hl_proc_cch_close_cfm
2715**
2716** Description      Process the CCH close confirmation
2717**
2718** Returns          Nothing
2719**
2720*******************************************************************************/
2721static void btif_hl_proc_cch_close_cfm(tBTA_HL *p_data)
2722{
2723    UINT8                   app_idx, mcl_idx;
2724    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
2725
2726    btif_hl_clean_mcb_using_handle(p_data->cch_close_ind.mcl_handle);
2727}
2728
2729/*******************************************************************************
2730**
2731** Function         btif_hl_proc_create_ind
2732**
2733** Description      Process the MDL create indication
2734**
2735** Returns          Nothing
2736**
2737*******************************************************************************/
2738static void btif_hl_proc_create_ind(tBTA_HL *p_data){
2739    btif_hl_app_cb_t         *p_acb;
2740    btif_hl_mcl_cb_t         *p_mcb;
2741    tBTA_HL_MDEP            *p_mdep;
2742    UINT8                   app_idx, orig_app_idx, mcl_idx, mdep_cfg_idx;
2743    BOOLEAN                 first_reliable_exist;
2744    BOOLEAN                 success = TRUE;
2745    tBTA_HL_DCH_CFG         rsp_cfg = BTA_HL_DCH_CFG_UNKNOWN;
2746    tBTA_HL_DCH_CREATE_RSP  rsp_code = BTA_HL_DCH_CREATE_RSP_CFG_REJ;
2747    tBTA_HL_DCH_CREATE_RSP_PARAM create_rsp_param;
2748
2749    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
2750
2751// Find the correct app_idx based on the mdep_id;
2752    btif_hl_find_app_idx_using_mdepId(p_data->dch_create_ind.local_mdep_id,&orig_app_idx);
2753    if (btif_hl_find_mcl_idx(orig_app_idx, p_data->dch_create_ind.bd_addr, &mcl_idx))
2754    {
2755        p_acb =BTIF_HL_GET_APP_CB_PTR(orig_app_idx);
2756        p_mcb =BTIF_HL_GET_MCL_CB_PTR(orig_app_idx, mcl_idx);
2757
2758        if (btif_hl_find_mdep_cfg_idx(orig_app_idx, p_data->dch_create_ind.local_mdep_id, &mdep_cfg_idx))
2759        {
2760            p_mdep = &(p_acb->sup_feature.mdep[mdep_cfg_idx]);
2761            first_reliable_exist = btif_hl_is_the_first_reliable_existed(orig_app_idx, mcl_idx);
2762            switch (p_mdep->mdep_cfg.mdep_role)
2763            {
2764                case BTA_HL_MDEP_ROLE_SOURCE:
2765                    if (p_data->dch_create_ind.cfg == BTA_HL_DCH_CFG_NO_PREF)
2766                    {
2767                        if (first_reliable_exist)
2768                        {
2769                            rsp_cfg = p_acb->channel_type[mdep_cfg_idx];
2770                        }
2771                        else
2772                        {
2773                            rsp_cfg = BTA_HL_DCH_CFG_RELIABLE;
2774                        }
2775                        rsp_code = BTA_HL_DCH_CREATE_RSP_SUCCESS;
2776                    }
2777
2778                    break;
2779                case BTA_HL_MDEP_ROLE_SINK:
2780
2781                    BTIF_TRACE_DEBUG0("btif_hl_proc_create_ind:BTA_HL_MDEP_ROLE_SINK");
2782                    if ((p_data->dch_create_ind.cfg  == BTA_HL_DCH_CFG_RELIABLE) ||
2783                        (first_reliable_exist && (p_data->dch_create_ind.cfg  == BTA_HL_DCH_CFG_STREAMING)))
2784                    {
2785                        rsp_code = BTA_HL_DCH_CREATE_RSP_SUCCESS;
2786                        rsp_cfg = p_data->dch_create_ind.cfg;
2787                        BTIF_TRACE_DEBUG1("btif_hl_proc_create_ind:BTA_HL_MDEP_ROLE_SINK cfg = %d",rsp_cfg);
2788                    }
2789                    break;
2790                default:
2791                    break;
2792            }
2793        }
2794    }
2795    else
2796    {
2797        success = FALSE;
2798    }
2799
2800    if (success)
2801    {
2802        BTIF_TRACE_DEBUG2("create response rsp_code=%d rsp_cfg=%d", rsp_code, rsp_cfg );
2803        create_rsp_param.local_mdep_id = p_data->dch_create_ind.local_mdep_id;
2804        create_rsp_param.mdl_id = p_data->dch_create_ind.mdl_id;
2805        create_rsp_param.rsp_code = rsp_code;
2806        create_rsp_param.cfg_rsp = rsp_cfg;
2807        BTA_HlDchCreateRsp(p_mcb->mcl_handle, &create_rsp_param);
2808    }
2809}
2810
2811/*******************************************************************************
2812**
2813** Function         btif_hl_proc_dch_open_ind
2814**
2815** Description      Process the DCH open indication
2816**
2817** Returns          Nothing
2818**
2819*******************************************************************************/
2820static void btif_hl_proc_dch_open_ind(tBTA_HL *p_data)
2821
2822{
2823    btif_hl_app_cb_t         *p_acb;
2824    btif_hl_mcl_cb_t         *p_mcb;
2825    btif_hl_mdl_cb_t         *p_dcb;
2826    UINT8                    app_idx,orig_app_idx, mcl_idx, mdl_idx, mdep_cfg_idx;
2827    UINT8                    dc_cfg;
2828    BOOLEAN close_dch = FALSE;
2829
2830    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
2831
2832    // Find the correct app_idx based on the mdep_id;
2833    btif_hl_find_app_idx_using_mdepId(p_data->dch_open_ind.local_mdep_id,&orig_app_idx);
2834
2835    if (btif_hl_find_mcl_idx_using_app_idx(p_data->dch_open_ind.mcl_handle, orig_app_idx, &mcl_idx ))
2836    {
2837        p_acb =BTIF_HL_GET_APP_CB_PTR(orig_app_idx);
2838        p_mcb =BTIF_HL_GET_MCL_CB_PTR(orig_app_idx, mcl_idx);
2839
2840        if (btif_hl_find_avail_mdl_idx(orig_app_idx, mcl_idx, &mdl_idx))
2841        {
2842            p_dcb = BTIF_HL_GET_MDL_CB_PTR(orig_app_idx, mcl_idx, mdl_idx);
2843
2844            if (btif_hl_find_mdep_cfg_idx(orig_app_idx, p_data->dch_open_ind.local_mdep_id, &mdep_cfg_idx))
2845            {
2846                p_dcb->in_use               = TRUE;
2847                p_dcb->mdl_handle           =  p_data->dch_open_ind.mdl_handle;
2848                p_dcb->local_mdep_cfg_idx   = mdep_cfg_idx;
2849                p_dcb->local_mdep_id        = p_data->dch_open_ind.local_mdep_id;
2850                p_dcb->mdl_id               = p_data->dch_open_ind.mdl_id;
2851                p_dcb->dch_mode             = p_data->dch_open_ind.dch_mode;
2852                p_dcb->dch_mode             = p_data->dch_open_ind.dch_mode;
2853                p_dcb->is_the_first_reliable = p_data->dch_open_ind.first_reliable;
2854                p_dcb->mtu                  = p_data->dch_open_ind.mtu;
2855
2856                if(btif_hl_find_channel_id_using_mdl_id(orig_app_idx,p_dcb->mdl_id , &p_dcb->channel_id))
2857                {
2858                    BTIF_TRACE_DEBUG4(" app_idx=%d mcl_idx=%d mdl_idx=%d channel_id=%d",
2859                                        app_idx, mcl_idx, mdl_idx, p_dcb->channel_id  );
2860                    if (!btif_hl_create_socket(orig_app_idx, mcl_idx, mdl_idx))
2861                    {
2862                        BTIF_TRACE_ERROR0("Unable to create socket");
2863                        close_dch = TRUE;
2864                    }
2865                }
2866                else
2867                {
2868                    BTIF_TRACE_ERROR1("Unable find channel id for mdl_id=0x%x", p_dcb->mdl_id  );
2869                    close_dch = TRUE;
2870                }
2871            }
2872            else
2873            {
2874                BTIF_TRACE_ERROR1("INVALID_LOCAL_MDEP_ID mdep_id=%d",p_data->dch_open_cfm.local_mdep_id);
2875                close_dch = TRUE;
2876            }
2877
2878            if (close_dch)
2879                btif_hl_clean_mdl_cb(p_dcb);
2880        }
2881        else
2882            close_dch = TRUE;
2883    }
2884    else
2885        close_dch = TRUE;
2886
2887    if (close_dch)
2888        BTA_HlDchClose(p_data->dch_open_cfm.mdl_handle);
2889}
2890
2891/*******************************************************************************
2892**
2893** Function         btif_hl_proc_dch_open_cfm
2894**
2895** Description      Process the DCH close confirmation
2896**
2897** Returns          Nothing
2898**
2899*******************************************************************************/
2900static BOOLEAN btif_hl_proc_dch_open_cfm(tBTA_HL *p_data)
2901
2902{
2903    btif_hl_app_cb_t            *p_acb;
2904    btif_hl_mcl_cb_t            *p_mcb;
2905    btif_hl_mdl_cb_t            *p_dcb;
2906    btif_hl_pending_chan_cb_t   *p_pcb;
2907    UINT8                    app_idx, mcl_idx, mdl_idx, mdep_cfg_idx;
2908    BOOLEAN                  status = FALSE;
2909    BOOLEAN                  close_dch = FALSE;
2910
2911    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
2912
2913    // Find the correct app_idx based on the mdep_id;
2914    btif_hl_find_app_idx_using_mdepId(p_data->dch_open_cfm.local_mdep_id,&app_idx);
2915
2916    if (btif_hl_find_mcl_idx_using_app_idx(p_data->dch_open_cfm.mcl_handle, app_idx, &mcl_idx ))
2917    {
2918        p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
2919        p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2920        p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
2921
2922        if (btif_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx))
2923        {
2924            p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2925
2926            if (btif_hl_find_mdep_cfg_idx(app_idx, p_data->dch_open_cfm.local_mdep_id, &mdep_cfg_idx))
2927            {
2928                p_dcb->in_use               = TRUE;
2929                p_dcb->mdl_handle           = p_data->dch_open_cfm.mdl_handle;
2930                p_dcb->local_mdep_cfg_idx   = mdep_cfg_idx;
2931                p_dcb->local_mdep_id        = p_data->dch_open_cfm.local_mdep_id;
2932                p_dcb->mdl_id               = p_data->dch_open_cfm.mdl_id;
2933                p_dcb->dch_mode             = p_data->dch_open_cfm.dch_mode;
2934                p_dcb->is_the_first_reliable= p_data->dch_open_cfm.first_reliable;
2935                p_dcb->mtu                  = p_data->dch_open_cfm.mtu;
2936                p_dcb->channel_id           = p_pcb->channel_id;
2937
2938                BTIF_TRACE_DEBUG3("app_idx=%d mcl_idx=%d mdl_idx=%d",  app_idx, mcl_idx, mdl_idx  );
2939                btif_hl_send_setup_connecting_cb(app_idx, mcl_idx);
2940                if (btif_hl_create_socket(app_idx, mcl_idx, mdl_idx))
2941                {
2942                    status = TRUE;
2943                    BTIF_TRACE_DEBUG4("app_idx=%d mcl_idx=%d mdl_idx=%d p_dcb->channel_id=0x%08x",
2944                                      app_idx, mcl_idx, mdl_idx, p_dcb->channel_id);
2945                    btif_hl_clean_pcb(p_pcb);
2946                }
2947                else
2948                {
2949                    BTIF_TRACE_ERROR0("Unable to create socket");
2950                    close_dch = TRUE;
2951                }
2952            }
2953            else
2954            {
2955                BTIF_TRACE_ERROR1("INVALID_LOCAL_MDEP_ID mdep_id=%d",p_data->dch_open_cfm.local_mdep_id);
2956                close_dch = TRUE;
2957            }
2958
2959            if (close_dch)
2960            {
2961                btif_hl_clean_mdl_cb(p_dcb);
2962                BTA_HlDchClose(p_data->dch_open_cfm.mdl_handle);
2963            }
2964        }
2965    }
2966
2967    return status;
2968}
2969/*******************************************************************************
2970**
2971** Function         btif_hl_proc_dch_reconnect_cfm
2972**
2973** Description      Process the DCH reconnect indication
2974**
2975** Returns          Nothing
2976**
2977*******************************************************************************/
2978static BOOLEAN btif_hl_proc_dch_reconnect_cfm(tBTA_HL *p_data)
2979{
2980    btif_hl_app_cb_t            *p_acb;
2981    btif_hl_mcl_cb_t            *p_mcb;
2982    btif_hl_mdl_cb_t            *p_dcb;
2983    btif_hl_pending_chan_cb_t   *p_pcb;
2984    UINT8                    app_idx, mcl_idx, mdl_idx, mdep_cfg_idx;
2985    BOOLEAN                  status = FALSE;
2986    BOOLEAN                  close_dch = FALSE;
2987
2988    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
2989
2990    btif_hl_find_app_idx_using_mdepId(p_data->dch_reconnect_cfm.local_mdep_id,&app_idx);
2991
2992    if (btif_hl_find_mcl_idx_using_app_idx(p_data->dch_reconnect_cfm.mcl_handle, app_idx, &mcl_idx ))
2993    {
2994        p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
2995        p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2996        p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
2997
2998        if (btif_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx))
2999        {
3000            p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
3001
3002            if (btif_hl_find_mdep_cfg_idx(app_idx, p_data->dch_reconnect_cfm.local_mdep_id, &mdep_cfg_idx))
3003            {
3004                p_dcb->in_use               = TRUE;
3005                p_dcb->mdl_handle           = p_data->dch_reconnect_cfm.mdl_handle;
3006                p_dcb->local_mdep_cfg_idx   = mdep_cfg_idx;
3007                p_dcb->local_mdep_id        = p_data->dch_reconnect_cfm.local_mdep_id;
3008                p_dcb->mdl_id               = p_data->dch_reconnect_cfm.mdl_id;
3009                p_dcb->dch_mode             = p_data->dch_reconnect_cfm.dch_mode;
3010                p_dcb->is_the_first_reliable= p_data->dch_reconnect_cfm.first_reliable;
3011                p_dcb->mtu                  = p_data->dch_reconnect_cfm.mtu;
3012                p_dcb->channel_id           = p_pcb->channel_id;
3013
3014                BTIF_TRACE_DEBUG3("app_idx=%d mcl_idx=%d mdl_idx=%d",  app_idx, mcl_idx, mdl_idx  );
3015                btif_hl_send_setup_connecting_cb(app_idx, mcl_idx);
3016                if (btif_hl_create_socket(app_idx, mcl_idx, mdl_idx))
3017                {
3018                    status = TRUE;
3019                    BTIF_TRACE_DEBUG4("app_idx=%d mcl_idx=%d mdl_idx=%d p_dcb->channel_id=0x%08x",
3020                                      app_idx, mcl_idx, mdl_idx, p_dcb->channel_id);
3021                    btif_hl_clean_pcb(p_pcb);
3022                }
3023                else
3024                {
3025                    BTIF_TRACE_ERROR0("Unable to create socket");
3026                    close_dch = TRUE;
3027                }
3028            }
3029            else
3030            {
3031                BTIF_TRACE_ERROR1("INVALID_LOCAL_MDEP_ID mdep_id=%d",p_data->dch_open_cfm.local_mdep_id);
3032                close_dch = TRUE;
3033            }
3034
3035            if (close_dch)
3036            {
3037                btif_hl_clean_mdl_cb(p_dcb);
3038                BTA_HlDchClose(p_data->dch_reconnect_cfm.mdl_handle);
3039            }
3040        }
3041    }
3042
3043    return status;
3044
3045}
3046/*******************************************************************************
3047**
3048** Function         btif_hl_proc_dch_reconnect_ind
3049**
3050** Description      Process the DCH reconnect indication
3051**
3052** Returns          Nothing
3053**
3054*******************************************************************************/
3055static void btif_hl_proc_dch_reconnect_ind(tBTA_HL *p_data)
3056
3057{
3058    btif_hl_app_cb_t        *p_acb;
3059    btif_hl_mcl_cb_t        *p_mcb;
3060    btif_hl_mdl_cb_t        *p_dcb;
3061    UINT8                   app_idx, mcl_idx, mdl_idx, mdep_cfg_idx, dc_cfg;
3062    BOOLEAN                 close_dch = FALSE;
3063
3064    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
3065
3066    // Find the correct app_idx based on the mdep_id;
3067    btif_hl_find_app_idx_using_mdepId(p_data->dch_reconnect_ind.local_mdep_id,&app_idx);
3068
3069    if (btif_hl_find_mcl_idx_using_app_idx(p_data->dch_reconnect_ind.mcl_handle, app_idx, &mcl_idx ))
3070    {
3071        p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
3072        BTIF_TRACE_DEBUG2("btif_hl_proc_dch_reconnect_ind: app_idx = %d, mcl_idx = %d",
3073                                app_idx, mcl_idx);
3074        p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
3075
3076        if (btif_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx))
3077        {
3078            p_dcb =BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
3079
3080            if (btif_hl_find_mdep_cfg_idx(app_idx, p_data->dch_reconnect_ind.local_mdep_id, &mdep_cfg_idx))
3081            {
3082                p_dcb->in_use               = TRUE;
3083                p_dcb->mdl_handle           = p_data->dch_reconnect_ind.mdl_handle;
3084                p_dcb->local_mdep_cfg_idx   = mdep_cfg_idx;
3085                p_dcb->local_mdep_id        = p_data->dch_reconnect_ind.local_mdep_id;
3086                p_dcb->mdl_id               = p_data->dch_reconnect_ind.mdl_id;
3087                p_dcb->dch_mode             = p_data->dch_reconnect_ind.dch_mode;
3088                p_dcb->dch_mode             = p_data->dch_reconnect_ind.dch_mode;
3089                p_dcb->is_the_first_reliable= p_data->dch_reconnect_ind.first_reliable;
3090                p_dcb->mtu                  = p_data->dch_reconnect_ind.mtu;
3091                p_dcb->channel_id           = btif_hl_get_next_channel_id(p_acb->app_id);
3092
3093                BTIF_TRACE_DEBUG4(" app_idx=%d mcl_idx=%d mdl_idx=%d channel_id=%d",
3094                                  app_idx, mcl_idx, mdl_idx, p_dcb->channel_id  );
3095                if (!btif_hl_create_socket(app_idx, mcl_idx, mdl_idx))
3096                {
3097                    BTIF_TRACE_ERROR0("Unable to create socket");
3098                    close_dch = TRUE;
3099                }
3100            }
3101            else
3102            {
3103                BTIF_TRACE_ERROR1("INVALID_LOCAL_MDEP_ID mdep_id=%d",p_data->dch_open_cfm.local_mdep_id);
3104                close_dch = TRUE;
3105            }
3106
3107            if (close_dch)
3108                btif_hl_clean_mdl_cb(p_dcb);
3109        }
3110        else
3111            close_dch = TRUE;
3112    }
3113    else
3114        close_dch = TRUE;
3115
3116    if (close_dch)
3117        BTA_HlDchClose(p_data->dch_reconnect_ind.mdl_handle);
3118
3119}
3120
3121/*******************************************************************************
3122**
3123** Function         btif_hl_proc_dch_close_ind
3124**
3125** Description      Process the DCH close indication
3126**
3127** Returns          Nothing
3128**
3129*******************************************************************************/
3130static void btif_hl_proc_dch_close_ind(tBTA_HL *p_data)
3131
3132{
3133    btif_hl_mdl_cb_t         *p_dcb;
3134    btif_hl_mcl_cb_t         *p_mcb;
3135    UINT8                   app_idx, mcl_idx, mdl_idx;
3136
3137    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
3138    if (btif_hl_find_mdl_idx_using_handle(p_data->dch_close_ind.mdl_handle,
3139                                          &app_idx, &mcl_idx, &mdl_idx ))
3140    {
3141        p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
3142        btif_hl_release_socket(app_idx,mcl_idx, mdl_idx);
3143        btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx);
3144        p_mcb =  BTIF_HL_GET_MCL_CB_PTR(app_idx,mcl_idx);
3145        btif_hl_clean_mdl_cb(p_dcb);
3146        if (!btif_hl_num_dchs_in_use(p_mcb->mcl_handle))
3147            btif_hl_start_cch_timer(app_idx, mcl_idx);
3148        BTIF_TRACE_DEBUG1("remote DCH close success mdl_idx=%d", mdl_idx);
3149    }
3150}
3151
3152/*******************************************************************************
3153**
3154** Function         btif_hl_proc_dch_close_cfm
3155**
3156** Description      Process the DCH reconnect confirmation
3157**
3158** Returns          Nothing
3159**
3160*******************************************************************************/
3161static void btif_hl_proc_dch_close_cfm(tBTA_HL *p_data)
3162
3163{
3164    btif_hl_mdl_cb_t         *p_dcb;
3165    btif_hl_mcl_cb_t         *p_mcb;
3166    UINT8                   app_idx, mcl_idx, mdl_idx;
3167
3168    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
3169    if (btif_hl_find_mdl_idx_using_handle(p_data->dch_close_cfm.mdl_handle,
3170                                          &app_idx, &mcl_idx, &mdl_idx ))
3171    {
3172        p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
3173        btif_hl_release_socket(app_idx,mcl_idx,mdl_idx);
3174        btif_hl_clean_mdl_cb(p_dcb);
3175        p_mcb =  BTIF_HL_GET_MCL_CB_PTR(app_idx,mcl_idx);
3176        if (!btif_hl_num_dchs_in_use(p_mcb->mcl_handle))
3177            btif_hl_start_cch_timer(app_idx, mcl_idx);
3178        BTIF_TRACE_DEBUG1(" local DCH close success mdl_idx=%d", mdl_idx);
3179    }
3180}
3181
3182
3183/*******************************************************************************
3184**
3185** Function         btif_hl_proc_abort_ind
3186**
3187** Description      Process the abort indicaiton
3188**
3189** Returns          Nothing
3190**
3191*******************************************************************************/
3192static void btif_hl_proc_abort_ind(tBTA_HL_MCL_HANDLE mcl_handle){
3193
3194    UINT8                   app_idx,mcl_idx;
3195    BTIF_TRACE_DEBUG1("%s", __FUNCTION__ );
3196    btif_hl_app_cb_t  *p_acb;
3197    UINT8 i,j;
3198
3199    for (i=0; i<BTA_HL_NUM_APPS; i++)
3200    {
3201        p_acb =BTIF_HL_GET_APP_CB_PTR(i);
3202        for (j=0; j < BTA_HL_NUM_MCLS ; j++)
3203        {
3204            if (p_acb->mcb[j].in_use)
3205                BTIF_TRACE_DEBUG3("btif_hl_find_mcl_idx_using_handle: app_idx=%d,mcl_idx =%d mcl_handle=%d",i,j,p_acb->mcb[j].mcl_handle);
3206            if (p_acb->mcb[j].in_use &&
3207                (p_acb->mcb[j].mcl_handle == mcl_handle))
3208            {
3209                btif_hl_stop_cch_timer(i, j);
3210                btif_hl_send_setup_disconnected_cb(i, j);
3211                btif_hl_clean_mcl_cb(i, j);
3212            }
3213        }
3214    }
3215}
3216
3217/*******************************************************************************
3218**
3219** Function         btif_hl_proc_abort_cfm
3220**
3221** Description      Process the abort confirmation
3222**
3223** Returns          Nothing
3224**
3225*******************************************************************************/
3226static void btif_hl_proc_abort_cfm(tBTA_HL_MCL_HANDLE mcl_handle){
3227    UINT8                   app_idx,mcl_idx;
3228
3229    BTIF_TRACE_DEBUG1("%s", __FUNCTION__ );
3230    btif_hl_app_cb_t  *p_acb;
3231    UINT8 i,j;
3232
3233    for (i=0; i<BTA_HL_NUM_APPS; i++)
3234    {
3235        p_acb =BTIF_HL_GET_APP_CB_PTR(i);
3236        for (j=0; j < BTA_HL_NUM_MCLS ; j++)
3237        {
3238            if (p_acb->mcb[j].in_use)
3239                BTIF_TRACE_DEBUG3("btif_hl_find_mcl_idx_using_handle: app_idx=%d,mcl_idx =%d mcl_handle=%d",i,j,p_acb->mcb[j].mcl_handle);
3240            if (p_acb->mcb[j].in_use &&
3241                (p_acb->mcb[j].mcl_handle == mcl_handle))
3242            {
3243                btif_hl_stop_cch_timer(i, j);
3244                btif_hl_send_setup_disconnected_cb(i, j);
3245                btif_hl_clean_mcl_cb(i, j);
3246            }
3247        }
3248    }
3249
3250}
3251
3252/*******************************************************************************
3253**
3254** Function         btif_hl_proc_send_data_cfm
3255**
3256** Description      Process the send data confirmation
3257**
3258** Returns          Nothing
3259**
3260*******************************************************************************/
3261static void btif_hl_proc_send_data_cfm(tBTA_HL_MDL_HANDLE mdl_handle,
3262                                       tBTA_HL_STATUS status){
3263    UINT8                   app_idx,mcl_idx, mdl_idx;
3264    btif_hl_mdl_cb_t         *p_dcb;
3265
3266    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
3267    if (btif_hl_find_mdl_idx_using_handle(mdl_handle,
3268                                          &app_idx, &mcl_idx, &mdl_idx ))
3269    {
3270        p_dcb =BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
3271        btif_hl_free_buf((void **) &p_dcb->p_tx_pkt);
3272        BTIF_TRACE_DEBUG1("send success free p_tx_pkt tx_size=%d", p_dcb->tx_size);
3273        p_dcb->tx_size = 0;
3274    }
3275}
3276
3277/*******************************************************************************
3278**
3279** Function         btif_hl_proc_dch_cong_ind
3280**
3281** Description      Process the DCH congestion change indication
3282**
3283** Returns          Nothing
3284**
3285*******************************************************************************/
3286static void btif_hl_proc_dch_cong_ind(tBTA_HL *p_data)
3287
3288{
3289    btif_hl_mdl_cb_t         *p_dcb;
3290    UINT8                   app_idx, mcl_idx, mdl_idx;
3291
3292    BTIF_TRACE_DEBUG0("btif_hl_proc_dch_cong_ind");
3293
3294
3295    if (btif_hl_find_mdl_idx_using_handle(p_data->dch_cong_ind.mdl_handle, &app_idx, &mcl_idx, &mdl_idx))
3296    {
3297        p_dcb =BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
3298        p_dcb->cong = p_data->dch_cong_ind.cong;
3299    }
3300}
3301
3302/*******************************************************************************
3303**
3304** Function         btif_hl_proc_cb_evt
3305**
3306** Description      Process registration request
3307**
3308** Returns          void
3309**
3310*******************************************************************************/
3311static void btif_hl_proc_reg_request(UINT8 app_idx, UINT8  app_id,
3312                                     tBTA_HL_REG_PARAM *p_reg_param,
3313                                     tBTA_HL_CBACK *p_cback){
3314    bt_status_t status= BT_STATUS_SUCCESS;
3315    UINT8 i;
3316    btif_hl_app_data_t *p_data;
3317    BTIF_TRACE_DEBUG3("%s app_idx=%d app_id=%d", __FUNCTION__, app_idx, app_id);
3318
3319    if(reg_counter >1)
3320    {
3321        BTIF_TRACE_DEBUG0("btif_hl_proc_reg_request: calling uPDATE");
3322        BTA_HlUpdate(app_id, p_reg_param,TRUE, btif_hl_cback);
3323    }
3324    else
3325        BTA_HlRegister(app_id, p_reg_param, btif_hl_cback);
3326}
3327
3328
3329/*******************************************************************************
3330**
3331** Function         btif_hl_proc_cb_evt
3332**
3333** Description      Process HL callback events
3334**
3335** Returns          void
3336**
3337*******************************************************************************/
3338static void btif_hl_proc_cb_evt(UINT16 event, char* p_param){
3339
3340    btif_hl_evt_cb_t                *p_data = (btif_hl_evt_cb_t *)p_param;
3341    bt_bdaddr_t                     bd_addr;
3342    bthl_channel_state_t            state=BTHL_CONN_STATE_DISCONNECTED;
3343    BOOLEAN                         send_chan_cb=TRUE;
3344    tBTA_HL_REG_PARAM               reg_param;
3345    btif_hl_app_cb_t                *p_acb;
3346    bthl_app_reg_state_t            reg_state = BTHL_APP_REG_STATE_REG_FAILED;
3347    int                             app_id;
3348    UINT8                           preg_idx;
3349    bt_status_t                     bt_status;
3350
3351    BTIF_TRACE_DEBUG2("%s event %d", __FUNCTION__, event);
3352    btif_hl_display_calling_process_name();
3353
3354    switch (event)
3355    {
3356        case BTIF_HL_SEND_CONNECTED_CB:
3357        case BTIF_HL_SEND_DISCONNECTED_CB:
3358            if (p_data->chan_cb.cb_state == BTIF_HL_CHAN_CB_STATE_CONNECTED_PENDING)
3359                state = BTHL_CONN_STATE_CONNECTED;
3360            else if (p_data->chan_cb.cb_state == BTIF_HL_CHAN_CB_STATE_DISCONNECTED_PENDING)
3361                state = BTHL_CONN_STATE_DISCONNECTED;
3362            else
3363                send_chan_cb = FALSE;
3364
3365            if (send_chan_cb)
3366            {
3367                btif_hl_copy_bda(&bd_addr, p_data->chan_cb.bd_addr);
3368                BTIF_TRACE_DEBUG4("state callbk: ch_id=0x%08x cb_state=%d state=%d  fd=%d",
3369                                  p_data->chan_cb.channel_id,
3370                                  p_data->chan_cb.cb_state,
3371                                  state,  p_data->chan_cb.fd);
3372                btif_hl_display_bt_bda(&bd_addr);
3373                BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb,  p_data->chan_cb.app_id,
3374                                   &bd_addr, p_data->chan_cb.mdep_cfg_index,
3375                                   p_data->chan_cb.channel_id, state, p_data->chan_cb.fd );
3376            }
3377
3378            break;
3379        case BTIF_HL_REG_APP:
3380            p_acb  = BTIF_HL_GET_APP_CB_PTR(p_data->reg.app_idx);
3381            app_id = (int) p_acb->app_id;
3382            BTIF_TRACE_DEBUG2("Rcv BTIF_HL_REG_APP app_idx=%d reg_pending=%d", p_data->reg.app_idx, p_acb->reg_pending);
3383            if (btif_hl_get_state() == BTIF_HL_STATE_ENABLED && p_acb->reg_pending)
3384            {
3385                BTIF_TRACE_DEBUG1("Rcv BTIF_HL_REG_APP reg_counter=%d",reg_counter);
3386                p_acb->reg_pending = FALSE;
3387                reg_param.dev_type = p_acb->dev_type;
3388                reg_param.sec_mask = BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT;
3389                reg_param.p_srv_name = p_acb->srv_name;
3390                reg_param.p_srv_desp = p_acb->srv_desp;
3391                reg_param.p_provider_name = p_acb->provider_name;
3392                btif_hl_proc_reg_request (p_data->reg.app_idx, p_acb->app_id, &reg_param, btif_hl_cback);
3393            }
3394            else
3395            {
3396                BTIF_TRACE_DEBUG2("reg request is processed state=%d reg_pending=%d", btif_hl_get_state(), p_acb->reg_pending);
3397            }
3398
3399            break;
3400
3401        case BTIF_HL_UNREG_APP:
3402            BTIF_TRACE_DEBUG1("Rcv BTIF_HL_UNREG_APP app_idx=%d", p_data->unreg.app_idx );
3403            p_acb = BTIF_HL_GET_APP_CB_PTR(p_data->unreg.app_idx);
3404            if (btif_hl_get_state() == BTIF_HL_STATE_ENABLED)
3405            {
3406                if(reg_counter >= 1)
3407                    BTA_HlUpdate(p_acb->app_id,NULL,FALSE,NULL);
3408                else
3409                    BTA_HlDeregister(p_acb->app_id, p_acb->app_handle);
3410            }
3411            break;
3412        case BTIF_HL_UPDATE_MDL:
3413            BTIF_TRACE_DEBUG1("Rcv BTIF_HL_UPDATE_MDL app_idx=%d", p_data->update_mdl.app_idx );
3414            p_acb = BTIF_HL_GET_APP_CB_PTR(p_data->update_mdl.app_idx);
3415            break;
3416
3417        default:
3418            BTIF_TRACE_ERROR1("Unknown event %d", event);
3419            break;
3420    }
3421}
3422
3423/*******************************************************************************
3424**
3425** Function         btif_hl_upstreams_evt
3426**
3427** Description      Process HL events
3428**
3429** Returns          void
3430**
3431*******************************************************************************/
3432static void btif_hl_upstreams_evt(UINT16 event, char* p_param){
3433    tBTA_HL *p_data = (tBTA_HL *)p_param;
3434    UINT8                 app_idx, mcl_idx;
3435    btif_hl_app_cb_t      *p_acb;
3436    btif_hl_mcl_cb_t      *p_mcb = NULL;
3437    BD_ADDR               bd_addr;
3438    btif_hl_pend_dch_op_t  pending_op;
3439    BOOLEAN status;
3440
3441    BTIF_TRACE_DEBUG2("%s event %d", __FUNCTION__, event);
3442    btif_hl_display_calling_process_name();
3443    switch (event)
3444    {
3445        case BTA_HL_REGISTER_CFM_EVT:
3446            BTIF_TRACE_DEBUG0("Rcv BTA_HL_REGISTER_CFM_EVT");
3447            BTIF_TRACE_DEBUG3("app_id=%d app_handle=%d status=%d ",
3448                              p_data->reg_cfm.app_id,
3449                              p_data->reg_cfm.app_handle,
3450                              p_data->reg_cfm.status );
3451
3452            btif_hl_proc_reg_cfm(p_data);
3453            break;
3454        case BTA_HL_SDP_INFO_IND_EVT:
3455            BTIF_TRACE_DEBUG0("Rcv BTA_HL_SDP_INFO_IND_EVT");
3456            BTIF_TRACE_DEBUG5("app_handle=%d ctrl_psm=0x%04x data_psm=0x%04x x_spec=%d mcap_sup_procs=0x%02x",
3457                              p_data->sdp_info_ind.app_handle,
3458                              p_data->sdp_info_ind.ctrl_psm,
3459                              p_data->sdp_info_ind.data_psm,
3460                              p_data->sdp_info_ind.data_x_spec,
3461                              p_data->sdp_info_ind.mcap_sup_procs);
3462            //btif_hl_proc_sdp_info_ind(p_data);
3463            break;
3464
3465        case BTA_HL_DEREGISTER_CFM_EVT:
3466            BTIF_TRACE_DEBUG0("Rcv BTA_HL_DEREGISTER_CFM_EVT");
3467            BTIF_TRACE_DEBUG2("app_handle=%d status=%d ",
3468                              p_data->dereg_cfm.app_handle,
3469                              p_data->dereg_cfm.status );
3470            btif_hl_proc_dereg_cfm(p_data);
3471            break;
3472
3473        case BTA_HL_SDP_QUERY_CFM_EVT:
3474            BTIF_TRACE_DEBUG0("Rcv BTA_HL_SDP_QUERY_CFM_EVT");
3475            BTIF_TRACE_DEBUG3("app_handle=%d app_id =%d,status =%d",
3476                              p_data->sdp_query_cfm.app_handle,p_data->sdp_query_cfm.app_id,
3477                              p_data->sdp_query_cfm.status);
3478
3479            BTIF_TRACE_DEBUG6("DB [%02x] [%02x] [%02x] [%02x] [%02x] [%02x]",
3480                              p_data->sdp_query_cfm.bd_addr[0], p_data->sdp_query_cfm.bd_addr[1],
3481                              p_data->sdp_query_cfm.bd_addr[2], p_data->sdp_query_cfm.bd_addr[3],
3482                              p_data->sdp_query_cfm.bd_addr[4], p_data->sdp_query_cfm.bd_addr[5]);
3483
3484            if (p_data->sdp_query_cfm.status == BTA_HL_STATUS_OK)
3485                status = btif_hl_proc_sdp_query_cfm(p_data);
3486            else
3487                status = FALSE;
3488
3489            if (!status)
3490            {
3491                BTIF_TRACE_DEBUG1("BTA_HL_SDP_QUERY_CFM_EVT Status = %d",
3492                                                        p_data->sdp_query_cfm.status);
3493                if (btif_hl_find_app_idx_using_app_id(p_data->sdp_query_cfm.app_id, &app_idx))
3494                {
3495                    p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
3496                    if (btif_hl_find_mcl_idx(app_idx, p_data->sdp_query_cfm.bd_addr, &mcl_idx))
3497                    {
3498                        p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
3499                        if ( (p_mcb->cch_oper ==  BTIF_HL_CCH_OP_MDEP_FILTERING) ||
3500                             (p_mcb->cch_oper == BTIF_HL_CCH_OP_DCH_OPEN) )
3501                        {
3502                            pending_op = p_mcb->pcb.op;
3503                            switch (pending_op)
3504                            {
3505                                case BTIF_HL_PEND_DCH_OP_OPEN:
3506                                    btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx);
3507                                    break;
3508                                case BTIF_HL_PEND_DCH_OP_RECONNECT:
3509                                case BTIF_HL_PEND_DCH_OP_DELETE_MDL:
3510                                default:
3511                                    break;
3512                            }
3513                            if (!p_mcb->is_connected)
3514                                btif_hl_clean_mcl_cb(app_idx, mcl_idx);
3515                        }
3516                    }
3517                }
3518            }
3519
3520            break;
3521
3522
3523        case BTA_HL_CCH_OPEN_CFM_EVT:
3524            BTIF_TRACE_DEBUG0("Rcv BTA_HL_CCH_OPEN_CFM_EVT");
3525            BTIF_TRACE_DEBUG4("app_id=%d,app_handle=%d mcl_handle=%d status =%d",
3526                              p_data->cch_open_cfm.app_id,
3527                              p_data->cch_open_cfm.app_handle,
3528                              p_data->cch_open_cfm.mcl_handle,
3529                              p_data->cch_open_cfm.status);
3530            BTIF_TRACE_DEBUG6("DB [%02x] [%02x] [%02x] [%02x] [%02x] [%02x]",
3531                              p_data->cch_open_cfm.bd_addr[0], p_data->cch_open_cfm.bd_addr[1],
3532                              p_data->cch_open_cfm.bd_addr[2], p_data->cch_open_cfm.bd_addr[3],
3533                              p_data->cch_open_cfm.bd_addr[4], p_data->cch_open_cfm.bd_addr[5]);
3534
3535            if (p_data->cch_open_cfm.status == BTA_HL_STATUS_OK ||
3536                        p_data->cch_open_cfm.status == BTA_HL_STATUS_DUPLICATE_CCH_OPEN)
3537            {
3538                status = btif_hl_proc_cch_open_cfm(p_data);
3539            }
3540            else
3541            {
3542                status = FALSE;
3543            }
3544
3545            if (!status)
3546            {
3547                if (btif_hl_find_app_idx_using_app_id(p_data->cch_open_cfm.app_id, &app_idx))
3548                {
3549                    p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
3550                    if (btif_hl_find_mcl_idx(app_idx, p_data->cch_open_cfm.bd_addr, &mcl_idx))
3551                    {
3552                        p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
3553                        pending_op = p_mcb->pcb.op;
3554                        switch (pending_op)
3555                        {
3556                            case BTIF_HL_PEND_DCH_OP_OPEN:
3557                                btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx);
3558                                break;
3559                            case BTIF_HL_PEND_DCH_OP_RECONNECT:
3560                            case BTIF_HL_PEND_DCH_OP_DELETE_MDL:
3561                            default:
3562                                break;
3563                        }
3564                        btif_hl_clean_mcl_cb(app_idx, mcl_idx);
3565                    }
3566                }
3567            }
3568            break;
3569
3570        case BTA_HL_DCH_OPEN_CFM_EVT:
3571            BTIF_TRACE_DEBUG0("Rcv BTA_HL_DCH_OPEN_CFM_EVT");
3572            BTIF_TRACE_DEBUG3("mcl_handle=%d mdl_handle=0x%x status=%d ",
3573                              p_data->dch_open_cfm.mcl_handle,
3574                              p_data->dch_open_cfm.mdl_handle,
3575                              p_data->dch_open_cfm.status);
3576            BTIF_TRACE_DEBUG5("first_reliable =%d dch_mode=%d local_mdep_id=%d mdl_id=%d mtu=%d",
3577                              p_data->dch_open_cfm.first_reliable,
3578                              p_data->dch_open_cfm.dch_mode,
3579                              p_data->dch_open_cfm.local_mdep_id,
3580                              p_data->dch_open_cfm.mdl_id,
3581                              p_data->dch_open_cfm.mtu);
3582            if (p_data->dch_open_cfm.status == BTA_HL_STATUS_OK)
3583            {
3584                status = btif_hl_proc_dch_open_cfm(p_data);
3585            }
3586            else
3587            {
3588                status = FALSE;
3589            }
3590
3591            if (!status)
3592            {
3593                if (btif_hl_find_mcl_idx_using_handle(p_data->dch_open_cfm.mcl_handle,&app_idx, &mcl_idx))
3594                {
3595                    p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
3596                    pending_op = p_mcb->pcb.op;
3597                    switch (pending_op)
3598                    {
3599                        case BTIF_HL_PEND_DCH_OP_OPEN:
3600                            btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx);
3601                            break;
3602                        case BTIF_HL_PEND_DCH_OP_RECONNECT:
3603                        case BTIF_HL_PEND_DCH_OP_DELETE_MDL:
3604                        default:
3605                            break;
3606                    }
3607                }
3608            }
3609            break;
3610
3611
3612        case BTA_HL_CCH_OPEN_IND_EVT:
3613            BTIF_TRACE_DEBUG0("Rcv BTA_HL_CCH_OPEN_IND_EVT");
3614            BTIF_TRACE_DEBUG2("app_handle=%d mcl_handle=%d",
3615                              p_data->cch_open_ind.app_handle,
3616                              p_data->cch_open_ind.mcl_handle);
3617            BTIF_TRACE_DEBUG6("DB [%02x] [%02x] [%02x] [%02x] [%02x] [%02x]",
3618                              p_data->cch_open_ind.bd_addr[0], p_data->cch_open_ind.bd_addr[1],
3619                              p_data->cch_open_ind.bd_addr[2], p_data->cch_open_ind.bd_addr[3],
3620                              p_data->cch_open_ind.bd_addr[4], p_data->cch_open_ind.bd_addr[5]);
3621
3622            btif_hl_proc_cch_open_ind(p_data);
3623            break;
3624
3625        case BTA_HL_DCH_CREATE_IND_EVT:
3626            BTIF_TRACE_DEBUG0("Rcv BTA_HL_DCH_CREATE_IND_EVT");
3627            BTIF_TRACE_DEBUG1("mcl_handle=%d",
3628                              p_data->dch_create_ind.mcl_handle );
3629            BTIF_TRACE_DEBUG3("local_mdep_id =%d mdl_id=%d cfg=%d",
3630                              p_data->dch_create_ind.local_mdep_id,
3631                              p_data->dch_create_ind.mdl_id,
3632                              p_data->dch_create_ind.cfg);
3633            btif_hl_proc_create_ind(p_data);
3634            break;
3635
3636        case BTA_HL_DCH_OPEN_IND_EVT:
3637            BTIF_TRACE_DEBUG0("Rcv BTA_HL_DCH_OPEN_IND_EVT");
3638            BTIF_TRACE_DEBUG2("mcl_handle=%d mdl_handle=0x%x",
3639                              p_data->dch_open_ind.mcl_handle,
3640                              p_data->dch_open_ind.mdl_handle );
3641            BTIF_TRACE_DEBUG5("first_reliable =%d dch_mode=%d local_mdep_id=%d mdl_id=%d mtu=%d",
3642                              p_data->dch_open_ind.first_reliable,
3643                              p_data->dch_open_ind.dch_mode,
3644                              p_data->dch_open_ind.local_mdep_id,
3645                              p_data->dch_open_ind.mdl_id,
3646                              p_data->dch_open_ind.mtu);
3647
3648            btif_hl_proc_dch_open_ind(p_data);
3649            break;
3650
3651        case BTA_HL_DELETE_MDL_IND_EVT:
3652            BTIF_TRACE_DEBUG0("Rcv BTA_HL_DELETE_MDL_IND_EVT");
3653            BTIF_TRACE_DEBUG2("mcl_handle=%d mdl_id=0x%x",
3654                              p_data->delete_mdl_ind.mcl_handle,
3655                              p_data->delete_mdl_ind.mdl_id);
3656            break;
3657
3658        case BTA_HL_DELETE_MDL_CFM_EVT:
3659            BTIF_TRACE_DEBUG0("Rcv BTA_HL_DELETE_MDL_CFM_EVT");
3660            BTIF_TRACE_DEBUG3("mcl_handle=%d mdl_id=0x%x status=%d",
3661                              p_data->delete_mdl_cfm.mcl_handle,
3662                              p_data->delete_mdl_cfm.mdl_id,
3663                              p_data->delete_mdl_cfm.status);
3664
3665            if (btif_hl_find_app_idx_using_deleted_mdl_id( p_data->delete_mdl_cfm.mdl_id,
3666                                    &app_idx))
3667            {
3668                p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
3669                btif_hl_send_destroyed_cb(p_acb);
3670                btif_hl_clean_delete_mdl(&p_acb->delete_mdl);
3671            }
3672            break;
3673
3674        case BTA_HL_DCH_RECONNECT_CFM_EVT:
3675            BTIF_TRACE_DEBUG0("Rcv BTA_HL_DCH_RECONNECT_CFM_EVT");
3676            BTIF_TRACE_DEBUG3("mcl_handle=%d mdl_handle=%d status=%d   ",
3677                              p_data->dch_reconnect_cfm.mcl_handle,
3678                              p_data->dch_reconnect_cfm.mdl_handle,
3679                              p_data->dch_reconnect_cfm.status);
3680            BTIF_TRACE_DEBUG4("first_reliable =%d dch_mode=%d mdl_id=%d mtu=%d",
3681                              p_data->dch_reconnect_cfm.first_reliable,
3682                              p_data->dch_reconnect_cfm.dch_mode,
3683                              p_data->dch_reconnect_cfm.mdl_id,
3684                              p_data->dch_reconnect_cfm.mtu);
3685
3686
3687            if (p_data->dch_reconnect_cfm.status == BTA_HL_STATUS_OK)
3688            {
3689                status = btif_hl_proc_dch_reconnect_cfm(p_data);
3690            }
3691            else
3692            {
3693                status = FALSE;
3694            }
3695
3696            if (!status)
3697            {
3698                if (btif_hl_find_mcl_idx_using_handle(p_data->dch_open_cfm.mcl_handle,&app_idx, &mcl_idx))
3699                {
3700                    p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
3701                    pending_op = p_mcb->pcb.op;
3702                    switch (pending_op)
3703                    {
3704                        case BTIF_HL_PEND_DCH_OP_OPEN:
3705                            btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx);
3706                            break;
3707                        case BTIF_HL_PEND_DCH_OP_RECONNECT:
3708                        case BTIF_HL_PEND_DCH_OP_DELETE_MDL:
3709                        default:
3710                            break;
3711                    }
3712                }
3713            }
3714
3715            break;
3716
3717        case BTA_HL_CCH_CLOSE_CFM_EVT:
3718            BTIF_TRACE_DEBUG0("Rcv BTA_HL_CCH_CLOSE_CFM_EVT");
3719            BTIF_TRACE_DEBUG2("mcl_handle=%d status =%d",
3720                              p_data->cch_close_cfm.mcl_handle,
3721                              p_data->cch_close_cfm.status);
3722            if (p_data->cch_close_cfm.status == BTA_HL_STATUS_OK)
3723            {
3724                btif_hl_proc_cch_close_cfm(p_data);
3725            }
3726            break;
3727
3728        case BTA_HL_CCH_CLOSE_IND_EVT:
3729            BTIF_TRACE_DEBUG0("Rcv BTA_HL_CCH_CLOSE_IND_EVT");
3730            BTIF_TRACE_DEBUG2("mcl_handle =%d intentional_close=%s",
3731                              p_data->cch_close_ind.mcl_handle,
3732                              (p_data->cch_close_ind.intentional?"Yes":"No"));
3733
3734            btif_hl_proc_cch_close_ind(p_data);
3735            break;
3736
3737        case BTA_HL_DCH_CLOSE_IND_EVT:
3738            BTIF_TRACE_DEBUG0("Rcv BTA_HL_DCH_CLOSE_IND_EVT");
3739            BTIF_TRACE_DEBUG2("mdl_handle=%d intentional_close=%s",
3740                              p_data->dch_close_ind.mdl_handle,
3741                              (p_data->dch_close_ind.intentional?"Yes":"No") );
3742
3743            btif_hl_proc_dch_close_ind(p_data);
3744            break;
3745
3746        case BTA_HL_DCH_CLOSE_CFM_EVT:
3747            BTIF_TRACE_DEBUG0("Rcv BTA_HL_DCH_CLOSE_CFM_EVT");
3748            BTIF_TRACE_DEBUG2("mdl_handle=%d status=%d ",
3749                              p_data->dch_close_cfm.mdl_handle,
3750                              p_data->dch_close_cfm.status);
3751
3752            if (p_data->dch_close_cfm.status == BTA_HL_STATUS_OK)
3753            {
3754                btif_hl_proc_dch_close_cfm(p_data);
3755            }
3756            break;
3757
3758        case BTA_HL_DCH_ECHO_TEST_CFM_EVT:
3759            BTIF_TRACE_DEBUG0("Rcv BTA_HL_DCH_ECHO_TEST_CFM_EVT");
3760            BTIF_TRACE_DEBUG2("mcl_handle=%d    status=%d",
3761                              p_data->echo_test_cfm.mcl_handle,
3762                              p_data->echo_test_cfm.status );
3763            /* not supported */
3764            break;
3765
3766
3767        case BTA_HL_DCH_RECONNECT_IND_EVT:
3768            BTIF_TRACE_DEBUG0("Rcv BTA_HL_DCH_RECONNECT_IND_EVT");
3769
3770            BTIF_TRACE_DEBUG2("mcl_handle=%d mdl_handle=5d",
3771                              p_data->dch_reconnect_ind.mcl_handle,
3772                              p_data->dch_reconnect_ind.mdl_handle );
3773            BTIF_TRACE_DEBUG4("first_reliable =%d dch_mode=%d mdl_id=%d mtu=%d",
3774                              p_data->dch_reconnect_ind.first_reliable,
3775                              p_data->dch_reconnect_ind.dch_mode,
3776                              p_data->dch_reconnect_ind.mdl_id,
3777                              p_data->dch_reconnect_ind.mtu);
3778
3779            btif_hl_proc_dch_reconnect_ind(p_data);
3780            break;
3781
3782        case BTA_HL_CONG_CHG_IND_EVT:
3783            BTIF_TRACE_DEBUG0("Rcv BTA_HL_CONG_CHG_IND_EVT");
3784            BTIF_TRACE_DEBUG2("mdl_handle=%d cong =%d",
3785                              p_data->dch_cong_ind.mdl_handle,
3786                              p_data->dch_cong_ind.cong);
3787            btif_hl_proc_dch_cong_ind(p_data);
3788            break;
3789
3790        case BTA_HL_DCH_ABORT_IND_EVT:
3791            BTIF_TRACE_DEBUG0("Rcv BTA_HL_DCH_ABORT_IND_EVT");
3792            BTIF_TRACE_DEBUG1("mcl_handle=%d",
3793                              p_data->dch_abort_ind.mcl_handle );
3794            btif_hl_proc_abort_ind(p_data->dch_abort_ind.mcl_handle);
3795            break;
3796        case BTA_HL_DCH_ABORT_CFM_EVT:
3797            BTIF_TRACE_DEBUG0("Rcv BTA_HL_DCH_ABORT_CFM_EVT");
3798            BTIF_TRACE_DEBUG2("mcl_handle=%d status =%d",
3799                              p_data->dch_abort_cfm.mcl_handle,
3800                              p_data->dch_abort_cfm.status);
3801            if (p_data->dch_abort_cfm.status == BTA_HL_STATUS_OK)
3802            {
3803                btif_hl_proc_abort_cfm(p_data->dch_abort_ind.mcl_handle);
3804            }
3805            break;
3806
3807        case BTA_HL_DCH_SEND_DATA_CFM_EVT:
3808            BTIF_TRACE_DEBUG0("Rcv BTA_HL_DCH_SEND_DATA_CFM_EVT");
3809            BTIF_TRACE_DEBUG2("mdl_handle=0x%x status =%d",
3810                              p_data->dch_send_data_cfm.mdl_handle,
3811                              p_data->dch_send_data_cfm.status);
3812            btif_hl_proc_send_data_cfm(p_data->dch_send_data_cfm.mdl_handle,
3813                                       p_data->dch_send_data_cfm.status);
3814            break;
3815
3816        case BTA_HL_DCH_RCV_DATA_IND_EVT:
3817            BTIF_TRACE_DEBUG0("Rcv BTA_HL_DCH_RCV_DATA_IND_EVT");
3818            BTIF_TRACE_DEBUG1("mdl_handle=0x%x ",
3819                              p_data->dch_rcv_data_ind.mdl_handle);
3820            /* do nothing here */
3821            break;
3822
3823        default:
3824            BTIF_TRACE_DEBUG1("Unknown Event (0x%02x)...", event);
3825            break;
3826    }
3827}
3828
3829/*******************************************************************************
3830**
3831** Function         btif_hl_cback
3832**
3833** Description      Callback function for HL events
3834**
3835** Returns          void
3836**
3837*******************************************************************************/
3838static void btif_hl_cback(tBTA_HL_EVT event, tBTA_HL *p_data){
3839    bt_status_t status;
3840    int param_len = 0;
3841    BTIF_TRACE_DEBUG2("%s event %d", __FUNCTION__, event);
3842    btif_hl_display_calling_process_name();
3843    switch (event)
3844    {
3845        case BTA_HL_REGISTER_CFM_EVT:
3846            param_len = sizeof(tBTA_HL_REGISTER_CFM);
3847            break;
3848        case BTA_HL_SDP_INFO_IND_EVT:
3849            param_len = sizeof(tBTA_HL_SDP_INFO_IND);
3850            break;
3851        case BTA_HL_DEREGISTER_CFM_EVT:
3852            param_len = sizeof(tBTA_HL_DEREGISTER_CFM);
3853            break;
3854        case BTA_HL_SDP_QUERY_CFM_EVT:
3855            param_len = sizeof(tBTA_HL_SDP_QUERY_CFM);
3856            break;
3857        case BTA_HL_CCH_OPEN_CFM_EVT:
3858            param_len = sizeof(tBTA_HL_CCH_OPEN_CFM);
3859            break;
3860        case BTA_HL_DCH_OPEN_CFM_EVT:
3861            param_len = sizeof(tBTA_HL_DCH_OPEN_CFM);
3862            break;
3863        case BTA_HL_CCH_OPEN_IND_EVT:
3864            param_len = sizeof(tBTA_HL_CCH_OPEN_IND);
3865            break;
3866        case BTA_HL_DCH_CREATE_IND_EVT:
3867            param_len = sizeof(tBTA_HL_DCH_CREATE_IND);
3868            break;
3869        case BTA_HL_DCH_OPEN_IND_EVT:
3870            param_len = sizeof(tBTA_HL_DCH_OPEN_IND);
3871            break;
3872        case BTA_HL_DELETE_MDL_IND_EVT:
3873            param_len = sizeof(tBTA_HL_MDL_IND);
3874            break;
3875        case BTA_HL_DELETE_MDL_CFM_EVT:
3876            param_len = sizeof(tBTA_HL_MDL_CFM);
3877            break;
3878        case BTA_HL_DCH_RECONNECT_CFM_EVT:
3879            param_len = sizeof(tBTA_HL_DCH_OPEN_CFM);
3880            break;
3881        case BTA_HL_CCH_CLOSE_CFM_EVT:
3882            param_len = sizeof(tBTA_HL_MCL_CFM);
3883            break;
3884        case BTA_HL_CCH_CLOSE_IND_EVT:
3885            param_len = sizeof(tBTA_HL_CCH_CLOSE_IND);
3886            break;
3887        case BTA_HL_DCH_CLOSE_IND_EVT:
3888            param_len = sizeof(tBTA_HL_DCH_CLOSE_IND);
3889            break;
3890        case BTA_HL_DCH_CLOSE_CFM_EVT:
3891            param_len = sizeof(tBTA_HL_MDL_CFM);
3892            break;
3893        case BTA_HL_DCH_ECHO_TEST_CFM_EVT:
3894            param_len = sizeof(tBTA_HL_MCL_CFM);
3895            break;
3896        case BTA_HL_DCH_RECONNECT_IND_EVT:
3897            param_len = sizeof(tBTA_HL_DCH_OPEN_IND);
3898            break;
3899        case BTA_HL_CONG_CHG_IND_EVT:
3900            param_len = sizeof(tBTA_HL_DCH_CONG_IND);
3901            break;
3902        case BTA_HL_DCH_ABORT_IND_EVT:
3903            param_len = sizeof(tBTA_HL_MCL_IND);
3904            break;
3905        case BTA_HL_DCH_ABORT_CFM_EVT:
3906            param_len = sizeof(tBTA_HL_MCL_CFM);
3907            break;
3908        case BTA_HL_DCH_SEND_DATA_CFM_EVT:
3909            param_len = sizeof(tBTA_HL_MDL_CFM);
3910            break;
3911        case BTA_HL_DCH_RCV_DATA_IND_EVT:
3912            param_len = sizeof(tBTA_HL_MDL_IND);
3913            break;
3914        default:
3915            param_len = sizeof(tBTA_HL_MDL_IND);
3916            break;
3917    }
3918    status = btif_transfer_context(btif_hl_upstreams_evt, (uint16_t)event, (void*)p_data, param_len, NULL);
3919
3920    /* catch any failed context transfers */
3921    ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
3922}
3923
3924/*******************************************************************************
3925**
3926** Function         btif_hl_upstreams_ctrl_evt
3927**
3928** Description      Callback function for HL control events in the BTIF task context
3929**
3930** Returns          void
3931**
3932*******************************************************************************/
3933static void btif_hl_upstreams_ctrl_evt(UINT16 event, char* p_param){
3934    tBTA_HL_CTRL *p_data = (tBTA_HL_CTRL *) p_param;
3935    UINT8               i;
3936    tBTA_HL_REG_PARAM   reg_param;
3937    btif_hl_app_cb_t    *p_acb;
3938
3939    BTIF_TRACE_DEBUG2("%s event %d", __FUNCTION__, event);
3940    btif_hl_display_calling_process_name();
3941
3942    switch ( event )
3943    {
3944        case BTA_HL_CTRL_ENABLE_CFM_EVT:
3945            BTIF_TRACE_DEBUG0("Rcv BTA_HL_CTRL_ENABLE_CFM_EVT");
3946            BTIF_TRACE_DEBUG1("status=%d", p_data->enable_cfm.status);
3947
3948            if (p_data->enable_cfm.status == BTA_HL_STATUS_OK)
3949            {
3950                btif_hl_set_state(BTIF_HL_STATE_ENABLED);
3951
3952
3953                for (i=0; i < BTA_HL_NUM_APPS ; i ++)
3954                {
3955                    p_acb = BTIF_HL_GET_APP_CB_PTR(i);
3956                    if (p_acb->in_use && p_acb->reg_pending)
3957                    {
3958                        p_acb->reg_pending = FALSE;
3959                        reg_param.dev_type = p_acb->dev_type;
3960                        reg_param.sec_mask = BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT;
3961                        reg_param.p_srv_name = p_acb->srv_name;
3962                        reg_param.p_srv_desp = p_acb->srv_desp;
3963                        reg_param.p_provider_name = p_acb->provider_name;
3964
3965                        BTIF_TRACE_DEBUG1("Register pending app_id=%d", p_acb->app_id);
3966                        btif_hl_proc_reg_request (i, p_acb->app_id, &reg_param, btif_hl_cback);
3967                    }
3968                }
3969            }
3970
3971            break;
3972        case BTA_HL_CTRL_DISABLE_CFM_EVT:
3973            BTIF_TRACE_DEBUG0("Rcv BTA_HL_CTRL_DISABLE_CFM_EVT");
3974            BTIF_TRACE_DEBUG1("status=%d",
3975                              p_data->disable_cfm.status);
3976
3977            if (p_data->disable_cfm.status == BTA_HL_STATUS_OK)
3978            {
3979                memset(p_btif_hl_cb, 0, sizeof(btif_hl_cb_t));
3980                btif_hl_set_state(BTIF_HL_STATE_DISABLED);
3981            }
3982
3983            break;
3984        default:
3985            break;
3986    }
3987}
3988
3989/*******************************************************************************
3990**
3991** Function         btif_hl_ctrl_cback
3992**
3993** Description      Callback function for HL control events
3994**
3995** Returns          void
3996**
3997*******************************************************************************/
3998static void btif_hl_ctrl_cback(tBTA_HL_CTRL_EVT event, tBTA_HL_CTRL *p_data){
3999    bt_status_t status;
4000    int param_len = 0;
4001
4002    BTIF_TRACE_DEBUG2("%s event %d", __FUNCTION__, event);
4003    btif_hl_display_calling_process_name();
4004
4005    switch ( event )
4006    {
4007        case BTA_HL_CTRL_ENABLE_CFM_EVT:
4008        case BTA_HL_CTRL_DISABLE_CFM_EVT:
4009            param_len = sizeof(tBTA_HL_CTRL_ENABLE_DISABLE);
4010            break;
4011        default:
4012            break;
4013    }
4014
4015    status = btif_transfer_context(btif_hl_upstreams_ctrl_evt, (uint16_t)event, (void*)p_data, param_len, NULL);
4016    ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
4017}
4018/*******************************************************************************
4019**
4020** Function         connect_channel
4021**
4022** Description     connect a data channel
4023**
4024** Returns         bt_status_t
4025**
4026*******************************************************************************/
4027static bt_status_t connect_channel(int app_id, bt_bdaddr_t *bd_addr, int mdep_cfg_index, int *channel_id){
4028    UINT8                   app_idx, mcl_idx;
4029    btif_hl_app_cb_t        *p_acb = NULL;
4030    btif_hl_pending_chan_cb_t   *p_pcb = NULL;
4031    btif_hl_mcl_cb_t        *p_mcb=NULL;
4032    bt_status_t             status = BT_STATUS_SUCCESS;
4033    tBTA_HL_DCH_OPEN_PARAM  dch_open;
4034    BD_ADDR                 bda;
4035    UINT8 i;
4036
4037    CHECK_BTHL_INIT();
4038    BTIF_TRACE_EVENT1("%s", __FUNCTION__);
4039    btif_hl_display_calling_process_name();
4040
4041
4042    for (i=0; i<6; i++)
4043    {
4044        bda[i] = (UINT8) bd_addr->address[i];
4045    }
4046    if (btif_hl_find_app_idx(((UINT8)app_id), &app_idx))
4047    {
4048        p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
4049        if (btif_hl_find_mcl_idx(app_idx, bda , &mcl_idx))
4050        {
4051            p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
4052            if (p_mcb->is_connected)
4053            {
4054                dch_open.ctrl_psm = p_mcb->ctrl_psm;
4055                dch_open.local_mdep_id = p_acb->sup_feature.mdep[mdep_cfg_index].mdep_id;
4056                BTIF_TRACE_DEBUG4("connect_channel: app_idx =%d, mdep_cfg_indx =%d, mdep_id =%d app_id= %d", app_idx,
4057                                                mdep_cfg_index, dch_open.local_mdep_id, app_id);
4058                if (btif_hl_find_peer_mdep_id(p_acb->app_id, p_mcb->bd_addr,
4059                                              p_acb->sup_feature.mdep[mdep_cfg_index].mdep_cfg.mdep_role,
4060                                              p_acb->sup_feature.mdep[mdep_cfg_index].mdep_cfg.data_cfg[0].data_type, &dch_open.peer_mdep_id ))
4061                {
4062                    dch_open.local_cfg = p_acb->channel_type[mdep_cfg_index];
4063                    if ((p_acb->sup_feature.mdep[mdep_cfg_index].mdep_cfg.mdep_role == BTA_HL_MDEP_ROLE_SOURCE)
4064                        && !btif_hl_is_the_first_reliable_existed(app_idx,mcl_idx))
4065                    {
4066                        dch_open.local_cfg = BTA_HL_DCH_CFG_RELIABLE;
4067                    }
4068                    dch_open.sec_mask = (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
4069
4070                    if( !btif_hl_dch_open(p_acb->app_id, bda, &dch_open,
4071                                              mdep_cfg_index, BTIF_HL_PEND_DCH_OP_OPEN, channel_id ))
4072                    {
4073                        status = BT_STATUS_FAIL;
4074                        BTIF_TRACE_EVENT1("%s loc0 status = BT_STATUS_FAIL", __FUNCTION__);
4075                    }
4076                }
4077                else
4078                {
4079                    p_mcb->cch_oper = BTIF_HL_CCH_OP_MDEP_FILTERING;
4080
4081                    p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
4082                    p_pcb->in_use = TRUE;
4083                    p_pcb->mdep_cfg_idx = mdep_cfg_index;
4084                    memcpy(p_pcb->bd_addr, bda, sizeof(BD_ADDR));
4085                    p_pcb->op = BTIF_HL_PEND_DCH_OP_OPEN;
4086                    BTA_HlSdpQuery(app_id,p_acb->app_handle, bda);
4087                }
4088            }
4089            else
4090            {
4091                status = BT_STATUS_FAIL;
4092            }
4093        }
4094        else
4095        {
4096            p_acb->filter.num_elems =1;
4097            p_acb->filter.elem[0].data_type = p_acb->sup_feature.mdep[mdep_cfg_index].mdep_cfg.data_cfg[mdep_cfg_index].data_type;
4098            if (p_acb->sup_feature.mdep[mdep_cfg_index].mdep_cfg.mdep_role == BTA_HL_MDEP_ROLE_SINK)
4099                p_acb->filter.elem[0].peer_mdep_role = BTA_HL_MDEP_ROLE_SOURCE;
4100            else
4101                p_acb->filter.elem[0].peer_mdep_role = BTA_HL_MDEP_ROLE_SINK;
4102
4103            if ( !btif_hl_cch_open(p_acb->app_id, bda, 0, mdep_cfg_index,
4104                                   BTIF_HL_PEND_DCH_OP_OPEN,
4105                                   channel_id))
4106            {
4107                status = BT_STATUS_FAIL;
4108            }
4109        }
4110    }
4111    else
4112    {
4113        status = BT_STATUS_FAIL;
4114    }
4115
4116    BTIF_TRACE_DEBUG3("%s status=%d channel_id=0x%08x", __FUNCTION__, status, *channel_id);
4117
4118    return status;
4119}
4120/*******************************************************************************
4121**
4122** Function         destroy_channel
4123**
4124** Description      destroy a data channel
4125**
4126** Returns         bt_status_t
4127**
4128*******************************************************************************/
4129static bt_status_t destroy_channel(int channel_id){
4130    UINT8 app_idx, mcl_idx, mdl_idx, mdl_cfg_idx, app_id, mdep_cfg_idx;
4131    bt_status_t status = BT_STATUS_SUCCESS;
4132    btif_hl_mdl_cfg_t     *p_mdl;
4133    btif_hl_mcl_cb_t     *p_mcb;
4134    btif_hl_mdl_cb_t     *p_dcb;
4135    btif_hl_app_cb_t     *p_acb;
4136
4137    CHECK_BTHL_INIT();
4138    BTIF_TRACE_EVENT2("%s channel_id=0x%08x", __FUNCTION__, channel_id);
4139    btif_hl_display_calling_process_name();
4140
4141
4142    if (btif_hl_if_channel_setup_pending(channel_id, &app_idx, &mcl_idx))
4143    {
4144        btif_hl_dch_abort(app_idx, mcl_idx);
4145    }
4146    else
4147    {
4148        if (btif_hl_find_mdl_cfg_idx_using_channel_id(channel_id, &app_idx, &mdl_cfg_idx))
4149 //       if(btif_hl_find_mdl_idx_using_channel_id(channel_id, &app_idx,&mcl_idx, &mdl_idx))
4150        {
4151            p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
4152            if (!p_acb->delete_mdl.active)
4153            {
4154                p_mdl =BTIF_HL_GET_MDL_CFG_PTR(app_idx, mdl_cfg_idx);
4155                p_acb->delete_mdl.active = TRUE;
4156                p_acb->delete_mdl.mdl_id = p_mdl->base.mdl_id;
4157                p_acb->delete_mdl.channel_id = channel_id;
4158                p_acb->delete_mdl.mdep_cfg_idx = p_mdl->extra.mdep_cfg_idx;
4159                memcpy(p_acb->delete_mdl.bd_addr, p_mdl->base.peer_bd_addr,sizeof(BD_ADDR));
4160
4161                if (btif_hl_find_mcl_idx(app_idx, p_mdl->base.peer_bd_addr, &mcl_idx))
4162                {
4163                    p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
4164                    if (p_mcb->is_connected)
4165                    {
4166                        BTIF_TRACE_DEBUG1("calling BTA_HlDeleteMdl mdl_id=%d",p_acb->delete_mdl.mdl_id );
4167                        BTA_HlDeleteMdl(p_mcb->mcl_handle, p_acb->delete_mdl.mdl_id);
4168                    }
4169                    else
4170                    {
4171                        status = BT_STATUS_FAIL;
4172                    }
4173                }
4174                else
4175                {
4176                    BTIF_TRACE_DEBUG0("btif_hl_delete_mdl calling btif_hl_cch_open"  );
4177                    mdep_cfg_idx = p_mdl->extra.mdep_cfg_idx;
4178                    p_acb->filter.num_elems =1;
4179                    p_acb->filter.elem[0].data_type = p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg.data_cfg[mdep_cfg_idx].data_type;
4180                    if (p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg.mdep_role == BTA_HL_MDEP_ROLE_SINK)
4181                        p_acb->filter.elem[0].peer_mdep_role = BTA_HL_MDEP_ROLE_SOURCE;
4182                    else
4183                        p_acb->filter.elem[0].peer_mdep_role = BTA_HL_MDEP_ROLE_SINK;
4184                    if (btif_hl_cch_open(p_acb->app_id, p_acb->delete_mdl.bd_addr, 0,
4185                                         mdep_cfg_idx,
4186                                         BTIF_HL_PEND_DCH_OP_DELETE_MDL, NULL))
4187                    {
4188                        status = BT_STATUS_FAIL;
4189                    }
4190                }
4191
4192                if (  status == BT_STATUS_FAIL)
4193                {
4194                    /* fail for now  */
4195                    btif_hl_clean_delete_mdl(&p_acb->delete_mdl);
4196                }
4197            }
4198            else
4199            {
4200                status = BT_STATUS_BUSY;
4201            }
4202        }
4203        else
4204        {
4205            status = BT_STATUS_FAIL;
4206        }
4207
4208    }
4209    return status;
4210}
4211/*******************************************************************************
4212**
4213** Function         unregister_application
4214**
4215** Description     unregister an HDP application
4216**
4217** Returns         bt_status_t
4218**
4219*******************************************************************************/
4220static bt_status_t unregister_application(int app_id){
4221    btif_hl_app_cb_t    *p_acb;
4222    UINT8               app_idx;
4223    int                 len;
4224    bt_status_t         status = BT_STATUS_SUCCESS;
4225    btif_hl_evt_cb_t    evt_param;
4226
4227    CHECK_BTHL_INIT();
4228    BTIF_TRACE_EVENT2("%s app_id=%d", __FUNCTION__, app_id);
4229    btif_hl_display_calling_process_name();
4230
4231    if (btif_hl_find_app_idx(((UINT8)app_id), &app_idx))
4232    {
4233        evt_param.unreg.app_idx = app_idx;
4234        p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
4235        reg_counter --;
4236        len = sizeof(btif_hl_unreg_t);
4237        status = btif_transfer_context (btif_hl_proc_cb_evt, BTIF_HL_UNREG_APP,
4238                                        (char*) &evt_param, len, NULL);
4239        ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
4240    }
4241    else
4242    {
4243        status  = BT_STATUS_FAIL;
4244    }
4245
4246    BTIF_TRACE_DEBUG1("de-reg return status=%d", status);
4247    return status;
4248}
4249/*******************************************************************************
4250**
4251** Function         register_application
4252**
4253** Description     register an HDP application
4254**
4255** Returns         bt_status_t
4256**
4257*******************************************************************************/
4258static bt_status_t register_application(bthl_reg_param_t *p_reg_param, int *app_id){
4259    btif_hl_app_cb_t            *p_acb;
4260    tBTA_HL_SUP_FEATURE         *p_sup;
4261    tBTA_HL_MDEP_CFG            *p_cfg;
4262    tBTA_HL_MDEP_DATA_TYPE_CFG  *p_data;
4263    UINT8                       app_idx=0, i=0, pending_reg_idx=0;
4264    bthl_mdep_cfg_t             *p_mdep_cfg;
4265    bt_status_t                 status = BT_STATUS_SUCCESS;
4266    btif_hl_evt_cb_t            evt_param;
4267    int                         len;
4268
4269    CHECK_BTHL_INIT();
4270    BTIF_TRACE_EVENT1("%s", __FUNCTION__);
4271    btif_hl_display_calling_process_name();
4272
4273    if (btif_hl_get_state() == BTIF_HL_STATE_DISABLED)
4274    {
4275        btif_hl_init();
4276        btif_hl_set_state(BTIF_HL_STATE_ENABLING);
4277        BTA_HlEnable(btif_hl_ctrl_cback);
4278    }
4279
4280    if (!btif_hl_find_avail_app_idx(&app_idx))
4281    {
4282        BTIF_TRACE_ERROR0("Unable to allocate a new application control block");
4283        return BT_STATUS_FAIL;
4284    }
4285
4286    p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
4287    p_acb->in_use = TRUE;
4288
4289
4290    p_acb->app_id = btif_hl_get_next_app_id();
4291
4292    if (p_reg_param->application_name != NULL )
4293        strncpy(p_acb->application_name, p_reg_param->application_name, BTIF_HL_APPLICATION_NAME_LEN);
4294
4295    if (p_reg_param->provider_name != NULL )
4296        strncpy(p_acb->provider_name, p_reg_param->provider_name, BTA_PROVIDER_NAME_LEN);
4297
4298    if (p_reg_param->srv_name != NULL )
4299        strncpy(p_acb->srv_name, p_reg_param->srv_name, BTA_SERVICE_NAME_LEN);
4300
4301    if (p_reg_param->srv_desp != NULL )
4302        strncpy(p_acb->srv_desp, p_reg_param->srv_desp, BTA_SERVICE_DESP_LEN);
4303
4304    p_sup = &p_acb->sup_feature;
4305    p_sup->advertize_source_sdp = TRUE;
4306    p_sup->echo_cfg.max_rx_apdu_size = BTIF_HL_ECHO_MAX_TX_RX_APDU_SIZE;
4307    p_sup->echo_cfg.max_tx_apdu_size = BTIF_HL_ECHO_MAX_TX_RX_APDU_SIZE;
4308    p_sup->num_of_mdeps = p_reg_param->number_of_mdeps;
4309
4310    for (i=0, p_mdep_cfg = p_reg_param->mdep_cfg ; i<  p_sup->num_of_mdeps; i++, p_mdep_cfg++  )
4311    {
4312        p_cfg = &p_sup->mdep[i].mdep_cfg;
4313        p_cfg->num_of_mdep_data_types = 1;
4314        p_data  = &p_cfg->data_cfg[0];
4315
4316        if ( !btif_hl_get_bta_mdep_role(p_mdep_cfg->mdep_role, &(p_cfg->mdep_role)))
4317        {
4318            BTIF_TRACE_ERROR1("Invalid mdep_role=%d", p_mdep_cfg->mdep_role);
4319            status = BT_STATUS_FAIL;
4320            break;
4321        }
4322        else
4323        {
4324            if (p_cfg->mdep_role == BTA_HL_MDEP_ROLE_SINK )
4325                p_sup->app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SINK;
4326            else
4327                p_sup->app_role_mask |=  BTA_HL_MDEP_ROLE_MASK_SOURCE;
4328
4329            if ( (p_sup->app_role_mask & BTA_HL_MDEP_ROLE_MASK_SINK) &&
4330                 (p_sup->app_role_mask & BTA_HL_MDEP_ROLE_MASK_SINK) )
4331            {
4332                p_acb->dev_type = BTA_HL_DEVICE_TYPE_DUAL;
4333            }
4334            else if ( p_sup->app_role_mask & BTA_HL_MDEP_ROLE_MASK_SINK )
4335                p_acb->dev_type = BTA_HL_DEVICE_TYPE_SINK;
4336            else
4337
4338                p_acb->dev_type = BTA_HL_DEVICE_TYPE_SOURCE;
4339
4340            p_data->data_type = (UINT16) p_mdep_cfg->data_type;
4341            p_data->max_rx_apdu_size = btif_hl_get_max_rx_apdu_size(p_cfg->mdep_role, p_data->data_type);
4342            p_data->max_tx_apdu_size = btif_hl_get_max_tx_apdu_size(p_cfg->mdep_role, p_data->data_type);
4343
4344            if (p_mdep_cfg->mdep_description != NULL )
4345                strncpy(p_data->desp, p_mdep_cfg->mdep_description, BTA_SERVICE_DESP_LEN);
4346
4347            if ( !btif_hl_get_bta_channel_type(p_mdep_cfg->channel_type, &(p_acb->channel_type[i])))
4348            {
4349                BTIF_TRACE_ERROR1("Invalid channel_type=%d", p_mdep_cfg->channel_type);
4350                status = BT_STATUS_FAIL;
4351                break;
4352            }
4353        }
4354    }
4355
4356    if (status == BT_STATUS_SUCCESS)
4357    {
4358        *app_id = (int) p_acb->app_id;
4359        evt_param.reg.app_idx = app_idx;
4360        len = sizeof(btif_hl_reg_t);
4361        p_acb->reg_pending = TRUE;
4362        reg_counter++;
4363        BTIF_TRACE_DEBUG2("calling btif_transfer_context status=%d app_id=%d", status, *app_id);
4364        status = btif_transfer_context (btif_hl_proc_cb_evt, BTIF_HL_REG_APP,
4365                                        (char*) &evt_param, len, NULL);
4366        ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
4367
4368    }
4369    else
4370    {
4371        btif_hl_free_app_idx(app_idx);
4372    }
4373
4374    BTIF_TRACE_DEBUG2("register_application status=%d app_id=%d", status, *app_id);
4375    return status;
4376}
4377
4378/*******************************************************************************
4379**
4380** Function      btif_hl_save_mdl_cfg
4381**
4382** Description  Save the MDL configuration
4383**
4384** Returns      BOOLEAN
4385**
4386*******************************************************************************/
4387BOOLEAN  btif_hl_save_mdl_cfg(UINT8 mdep_id, UINT8 item_idx,
4388                              tBTA_HL_MDL_CFG *p_mdl_cfg){
4389    btif_hl_mdl_cfg_t   *p_mdl=NULL;
4390    BOOLEAN             success = FALSE;
4391    btif_hl_app_cb_t    *p_acb;
4392    btif_hl_mcl_cb_t    *p_mcb;
4393    UINT8               app_idx, mcl_idx, mdl_idx, len;
4394    bt_status_t         bt_status;
4395    btif_hl_evt_cb_t    evt_param;
4396    int                 *p_channel_id;
4397
4398    BTIF_TRACE_DEBUG6("%s mdep_id=%d item_idx=%d, local_mdep_id=%d mdl_id=0x%x dch_mode=%d",
4399                      __FUNCTION__, mdep_id, item_idx, p_mdl_cfg->local_mdep_id,
4400                      p_mdl_cfg->mdl_id, p_mdl_cfg->dch_mode );
4401
4402    if(btif_hl_find_app_idx_using_mdepId(mdep_id,&app_idx))
4403    {
4404        p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
4405        p_mdl = BTIF_HL_GET_MDL_CFG_PTR(app_idx, item_idx);
4406        p_channel_id = BTIF_HL_GET_MDL_CFG_CHANNEL_ID_PTR(app_idx, item_idx);
4407        if (p_mdl)
4408        {
4409            memcpy(&p_mdl->base, p_mdl_cfg, sizeof(tBTA_HL_MDL_CFG));
4410            if (btif_hl_find_mcl_idx(app_idx, p_mdl->base.peer_bd_addr , &mcl_idx))
4411            {
4412                p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
4413                if (p_mcb->pcb.in_use)
4414                    *p_channel_id = p_mcb->pcb.channel_id;
4415                else
4416                    *p_channel_id = btif_hl_get_next_channel_id(p_acb->app_id);
4417                p_mdl->extra.mdep_cfg_idx = p_mcb->pcb.mdep_cfg_idx;
4418                p_mdl->extra.data_type = p_acb->sup_feature.mdep[p_mcb->pcb.mdep_cfg_idx].mdep_cfg.data_cfg[0].data_type;
4419
4420                if (!btif_hl_find_peer_mdep_id(p_acb->app_id, p_mcb->bd_addr,
4421                                               p_acb->sup_feature.mdep[p_mcb->pcb.mdep_cfg_idx].mdep_cfg.mdep_role,
4422                                               p_acb->sup_feature.mdep[p_mcb->pcb.mdep_cfg_idx].mdep_cfg.data_cfg[0].data_type,
4423                                               &p_mdl->extra.peer_mdep_id))
4424                {
4425                    p_mdl->extra.peer_mdep_id = BTA_HL_INVALID_MDEP_ID;
4426                }
4427                BTIF_TRACE_DEBUG4("%s app_idx=%d item_idx=%d mld_id=0x%x",
4428                                  __FUNCTION__, app_idx, item_idx, p_mdl->base.mdl_id);
4429                evt_param.update_mdl.app_idx = app_idx;
4430                len = sizeof(btif_hl_update_mdl_t);
4431                BTIF_TRACE_DEBUG1("send BTIF_HL_UPDATE_MDL event app_idx=%d  ",app_idx);
4432                if ((bt_status = btif_transfer_context (btif_hl_proc_cb_evt, BTIF_HL_UPDATE_MDL,
4433                                                        (char*) &evt_param, len, NULL)) == BT_STATUS_SUCCESS)
4434                {
4435                    success = TRUE;
4436                }
4437                ASSERTC(bt_status == BT_STATUS_SUCCESS, "context transfer failed", bt_status);
4438            }
4439        }
4440    }
4441    BTIF_TRACE_DEBUG2("%s success=%d  ",__FUNCTION__, success );
4442
4443    return success;
4444}
4445
4446/*******************************************************************************
4447**
4448** Function      btif_hl_delete_mdl_cfg
4449**
4450** Description  Delete the MDL configuration
4451**
4452** Returns      BOOLEAN
4453**
4454*******************************************************************************/
4455BOOLEAN  btif_hl_delete_mdl_cfg(UINT8 mdep_id, UINT8 item_idx){
4456    btif_hl_mdl_cfg_t     *p_mdl=NULL;
4457    BOOLEAN             success = FALSE;
4458    btif_hl_app_cb_t      *p_acb;
4459    UINT8               app_idx, len;
4460    bt_status_t         bt_status;
4461    btif_hl_evt_cb_t    evt_param;
4462
4463    if(btif_hl_find_app_idx_using_mdepId(mdep_id,&app_idx))
4464    {
4465
4466        p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
4467
4468        p_mdl = BTIF_HL_GET_MDL_CFG_PTR(app_idx, item_idx);
4469        if (p_mdl)
4470        {
4471            memset(p_mdl, 0, sizeof(btif_hl_mdl_cfg_t));
4472            evt_param.update_mdl.app_idx = app_idx;
4473            len = sizeof(btif_hl_update_mdl_t);
4474            BTIF_TRACE_DEBUG1("send BTIF_HL_UPDATE_MDL event app_idx=%d  ",app_idx);
4475            if ((bt_status = btif_transfer_context (btif_hl_proc_cb_evt, BTIF_HL_UPDATE_MDL,
4476                                                    (char*) &evt_param, len, NULL)) == BT_STATUS_SUCCESS)
4477            {
4478                success = TRUE;
4479            }
4480            ASSERTC(bt_status == BT_STATUS_SUCCESS, "context transfer failed", bt_status);
4481        }
4482    }
4483
4484    BTIF_TRACE_DEBUG2("%s success=%d  ",__FUNCTION__, success );
4485    return success;
4486}
4487
4488/*******************************************************************************
4489**
4490** Function         get_device_datatype
4491**
4492** Description      Start SDP on remote device and look for Remote HDP Data type and role
4493**
4494** Returns         bt_status_t
4495**
4496*******************************************************************************/
4497static bt_status_t get_device_datatype(int app_id, bt_bdaddr_t *bd_addr){
4498    btif_hl_app_cb_t    *p_acb;
4499    UINT8               app_idx;
4500    bt_status_t         status = BT_STATUS_SUCCESS;
4501    BD_ADDR             bda;
4502    UINT8               i;
4503
4504    CHECK_BTHL_INIT();
4505    BTIF_TRACE_EVENT2("%s app_id=%d", __FUNCTION__, app_id);
4506    btif_hl_display_calling_process_name();
4507
4508    for (i=0; i<6; i++)
4509    {
4510        bda[i] = (UINT8) bd_addr->address[i];
4511    }
4512
4513    if (btif_hl_find_app_idx(((UINT8)app_id), &app_idx))
4514    {
4515        p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
4516        BTA_HlSdpQuery(app_id,p_acb->app_handle,bda);
4517    }
4518    else
4519    {
4520        status  = BT_STATUS_FAIL;
4521    }
4522
4523    BTIF_TRACE_DEBUG1("de-reg return status=%d", status);
4524    return status;
4525}
4526
4527/*******************************************************************************
4528**
4529** Function         init
4530**
4531** Description     initializes the hl interface
4532**
4533** Returns         bt_status_t
4534**
4535*******************************************************************************/
4536static bt_status_t init( bthl_callbacks_t* callbacks ){
4537    bt_status_t status = BT_STATUS_SUCCESS;
4538
4539    BTIF_TRACE_EVENT1("%s", __FUNCTION__);
4540    btif_hl_display_calling_process_name();
4541    bt_hl_callbacks_cb = *callbacks;
4542    bt_hl_callbacks = &bt_hl_callbacks_cb;
4543    btif_hl_soc_thread_init();
4544    reg_counter = 0;
4545    return status;
4546}
4547/*******************************************************************************
4548**
4549** Function         cleanup
4550**
4551** Description      Closes the HL interface
4552**
4553** Returns          void
4554**
4555*******************************************************************************/
4556static void  cleanup( void ){
4557    BTIF_TRACE_EVENT1("%s", __FUNCTION__);
4558    btif_hl_display_calling_process_name();
4559    if (bt_hl_callbacks)
4560    {
4561        btif_disable_service(BTA_HDP_SERVICE_ID);
4562        bt_hl_callbacks = NULL;
4563        reg_counter = 0;
4564    }
4565
4566    btif_hl_disable();
4567    btif_hl_close_select_thread();
4568}
4569
4570static const bthl_interface_t bthlInterface = {
4571    sizeof(bthl_interface_t),
4572    init,
4573    register_application,
4574    unregister_application,
4575    connect_channel,
4576    destroy_channel,
4577    cleanup,
4578};
4579
4580
4581/*******************************************************************************
4582**
4583** Function         btif_hl_get_interface
4584**
4585** Description      Get the hl callback interface
4586**
4587** Returns          bthf_interface_t
4588**
4589*******************************************************************************/
4590const bthl_interface_t *btif_hl_get_interface(){
4591    BTIF_TRACE_EVENT1("%s", __FUNCTION__);
4592    return &bthlInterface;
4593}
4594
4595/*******************************************************************************
4596**
4597** Function btif_hl_update_maxfd
4598**
4599** Description Update the max fd if the input fd is greater than the current max fd
4600**
4601** Returns int
4602**
4603*******************************************************************************/
4604int btif_hl_update_maxfd( int max_org_s){
4605    btif_hl_soc_cb_t      *p_scb = NULL;
4606    int maxfd=0;
4607
4608    BTIF_TRACE_DEBUG1("btif_hl_update_maxfd max_org_s= %d", max_org_s);
4609
4610    maxfd = max_org_s;
4611    if (!GKI_queue_is_empty(&soc_queue))
4612    {
4613        p_scb = (btif_hl_soc_cb_t *)GKI_getfirst((void *)&soc_queue);
4614        if (maxfd < p_scb->max_s)
4615        {
4616            maxfd = p_scb->max_s;
4617            BTIF_TRACE_DEBUG1("btif_hl_update_maxfd 1 maxfd=%d", maxfd);
4618        }
4619        while (p_scb != NULL)
4620        {
4621            if (maxfd < p_scb->max_s)
4622            {
4623                maxfd = p_scb->max_s;
4624                BTIF_TRACE_DEBUG1("btif_hl_update_maxfd 2 maxfd=%d", maxfd);
4625            }
4626            p_scb = (btif_hl_soc_cb_t *)GKI_getnext((void *)p_scb );
4627        }
4628    }
4629
4630    BTIF_TRACE_DEBUG1("btif_hl_update_maxfd final *p_max_s=%d", maxfd);
4631    return maxfd;
4632}
4633/*******************************************************************************
4634**
4635** Function btif_hl_get_socket_state
4636**
4637** Description get socket state
4638**
4639** Returns btif_hl_soc_state_t
4640**
4641*******************************************************************************/
4642btif_hl_soc_state_t btif_hl_get_socket_state(btif_hl_soc_cb_t *p_scb){
4643    BTIF_TRACE_DEBUG1("btif_hl_get_socket_state state=%d", p_scb->state);
4644    return p_scb->state;
4645}
4646/*******************************************************************************
4647**
4648** Function btif_hl_set_socket_state
4649**
4650** Description set socket state
4651**
4652** Returns void
4653**
4654*******************************************************************************/
4655void btif_hl_set_socket_state(btif_hl_soc_cb_t *p_scb, btif_hl_soc_state_t new_state){
4656    BTIF_TRACE_DEBUG2("btif_hl_set_socket_state %d---->%d", p_scb->state, new_state);
4657    p_scb->state = new_state;
4658}
4659/*******************************************************************************
4660**
4661** Function btif_hl_release_mcl_sockets
4662**
4663** Description Release all sockets on the MCL
4664**
4665** Returns void
4666**
4667*******************************************************************************/
4668void btif_hl_release_mcl_sockets(UINT8 app_idx, UINT8 mcl_idx){
4669    btif_hl_soc_cb_t    *p_scb = NULL;
4670    UINT8               i;
4671    btif_hl_mdl_cb_t    *p_dcb;
4672    BOOLEAN             found= FALSE;
4673    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
4674    for (i=0; i < BTA_HL_NUM_MDLS_PER_MCL ; i ++)
4675    {
4676        p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, i);
4677        if (p_dcb && p_dcb->in_use && p_dcb->p_scb)
4678        {
4679            BTIF_TRACE_DEBUG3("found socket for app_idx=%d mcl_id=%d, mdl_idx=%d", app_idx, mcl_idx, i);
4680            btif_hl_set_socket_state (p_dcb->p_scb, BTIF_HL_SOC_STATE_W4_REL);
4681            p_dcb->p_scb = NULL;
4682            found = TRUE;
4683        }
4684    }
4685    if (found)
4686        btif_hl_select_close_connected();
4687}
4688/*******************************************************************************
4689**
4690** Function btif_hl_release_socket
4691**
4692** Description release a specified socket
4693**
4694** Returns void
4695**
4696*******************************************************************************/
4697void btif_hl_release_socket(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx){
4698    btif_hl_soc_cb_t       *p_scb = NULL;
4699    btif_hl_mdl_cb_t      *p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
4700
4701    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
4702    BTIF_TRACE_DEBUG3("app_idx=%d mcl_idx=%d mdl_idx=%d",  app_idx, mcl_idx, mdl_idx  );
4703
4704    if (p_dcb && p_dcb->p_scb)
4705    {
4706        p_scb = p_dcb->p_scb;
4707        btif_hl_set_socket_state(p_scb,  BTIF_HL_SOC_STATE_W4_REL);
4708        p_dcb->p_scb = NULL;
4709        btif_hl_select_close_connected();
4710    }
4711}
4712/*******************************************************************************
4713**
4714** Function btif_hl_create_socket
4715**
4716** Description create a socket
4717**
4718** Returns BOOLEAN
4719**
4720*******************************************************************************/
4721BOOLEAN btif_hl_create_socket(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx){
4722    btif_hl_mcl_cb_t      *p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
4723    btif_hl_mdl_cb_t      *p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
4724    btif_hl_soc_cb_t      *p_scb = NULL;
4725    UINT8                 soc_idx;
4726    BOOLEAN               status = FALSE;
4727
4728    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
4729
4730    if (p_dcb && ((p_scb = (btif_hl_soc_cb_t *)GKI_getbuf((UINT16)sizeof(btif_hl_soc_cb_t)))!=NULL))
4731    {
4732        if (socketpair(AF_UNIX, SOCK_STREAM, 0, p_scb->socket_id) >= 0)
4733        {
4734            BTIF_TRACE_DEBUG2("socket id[0]=%d id[1]=%d",p_scb->socket_id[0], p_scb->socket_id[1] );
4735            p_dcb->p_scb = p_scb;
4736            p_scb->app_idx = app_idx;
4737            p_scb->mcl_idx = mcl_idx;
4738            p_scb->mdl_idx = mdl_idx;
4739            p_scb->channel_id = p_dcb->channel_id;
4740            p_scb->mdep_cfg_idx = p_dcb->local_mdep_cfg_idx;
4741            memcpy(p_scb->bd_addr, p_mcb->bd_addr,sizeof(BD_ADDR));
4742            btif_hl_set_socket_state(p_scb,  BTIF_HL_SOC_STATE_W4_ADD);
4743            p_scb->max_s = p_scb->socket_id[1];
4744            GKI_enqueue(&soc_queue, (void *) p_scb);
4745            btif_hl_select_wakeup();
4746            status = TRUE;
4747        }
4748        else
4749        {
4750
4751            btif_hl_free_buf((void **)&p_scb);
4752        }
4753    }
4754
4755    BTIF_TRACE_DEBUG2("%s status=%d", __FUNCTION__, status);
4756    return status;
4757}
4758/*******************************************************************************
4759**
4760** Function btif_hl_add_socket_to_set
4761**
4762** Description Add a socket
4763**
4764** Returns void
4765**
4766*******************************************************************************/
4767void btif_hl_add_socket_to_set( fd_set *p_org_set){
4768    btif_hl_soc_cb_t                *p_scb = NULL;
4769    btif_hl_mdl_cb_t                *p_dcb = NULL;
4770    btif_hl_mcl_cb_t                *p_mcb = NULL;
4771    btif_hl_app_cb_t                *p_acb = NULL;
4772    btif_hl_evt_cb_t                evt_param;
4773    bt_status_t                     status;
4774    int                             len;
4775
4776    BTIF_TRACE_DEBUG1("entering %s",__FUNCTION__);
4777
4778    if (!GKI_queue_is_empty(&soc_queue))
4779    {
4780        p_scb = (btif_hl_soc_cb_t *)GKI_getfirst((void *)&soc_queue);
4781        BTIF_TRACE_DEBUG1("btif_hl_add_socket_to_set first p_scb=0x%x", p_scb);
4782        while (p_scb != NULL)
4783        {
4784            if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_W4_ADD)
4785            {
4786                btif_hl_set_socket_state(p_scb,   BTIF_HL_SOC_STATE_W4_READ);
4787                FD_SET(p_scb->socket_id[1], p_org_set);
4788                BTIF_TRACE_DEBUG2("found and set socket_id=%d is_set=%d", p_scb->socket_id[1], FD_ISSET(p_scb->socket_id[1], p_org_set));
4789                p_mcb = BTIF_HL_GET_MCL_CB_PTR(p_scb->app_idx, p_scb->mcl_idx);
4790                p_dcb = BTIF_HL_GET_MDL_CB_PTR(p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx);
4791                p_acb = BTIF_HL_GET_APP_CB_PTR(p_scb->app_idx);
4792                if (p_mcb && p_dcb)
4793                {
4794                    btif_hl_stop_timer_using_handle(p_mcb->mcl_handle);
4795                    evt_param.chan_cb.app_id = p_acb->app_id;
4796                    memcpy(evt_param.chan_cb.bd_addr, p_mcb->bd_addr, sizeof(BD_ADDR));
4797                    evt_param.chan_cb.channel_id = p_dcb->channel_id;
4798                    evt_param.chan_cb.fd = p_scb->socket_id[0];
4799                    evt_param.chan_cb.mdep_cfg_index = (int ) p_dcb->local_mdep_cfg_idx;
4800                    evt_param.chan_cb.cb_state = BTIF_HL_CHAN_CB_STATE_CONNECTED_PENDING;
4801                    len = sizeof(btif_hl_send_chan_state_cb_t);
4802                    status = btif_transfer_context (btif_hl_proc_cb_evt, BTIF_HL_SEND_CONNECTED_CB,
4803                                                    (char*) &evt_param, len, NULL);
4804                    ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
4805                }
4806            }
4807            p_scb = (btif_hl_soc_cb_t *)GKI_getnext((void *)p_scb );
4808            BTIF_TRACE_DEBUG1("next p_scb=0x%x", p_scb);
4809        }
4810    }
4811
4812    BTIF_TRACE_DEBUG1("leaving %s",__FUNCTION__);
4813}
4814/*******************************************************************************
4815**
4816** Function btif_hl_close_socket
4817**
4818** Description close a socket
4819**
4820** Returns void
4821**
4822*******************************************************************************/
4823void btif_hl_close_socket( fd_set *p_org_set){
4824    btif_hl_soc_cb_t                *p_scb = NULL;
4825    BOOLEAN                         element_removed = FALSE;
4826    btif_hl_mdl_cb_t                *p_dcb = NULL ;
4827    btif_hl_app_cb_t                *p_acb = NULL ;
4828    btif_hl_evt_cb_t                evt_param;
4829    int                             len;
4830    int                             app_idx;
4831    bt_status_t                     status;
4832
4833    BTIF_TRACE_DEBUG1("entering %s",__FUNCTION__);
4834    if (!GKI_queue_is_empty(&soc_queue))
4835    {
4836        p_scb = (btif_hl_soc_cb_t *)GKI_getfirst((void *)&soc_queue);
4837        while (p_scb != NULL)
4838        {
4839            if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_W4_REL)
4840            {
4841                BTIF_TRACE_DEBUG3("app_idx=%d mcl_id=%d, mdl_idx=%d",
4842                                  p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx);
4843                btif_hl_set_socket_state(p_scb,   BTIF_HL_SOC_STATE_IDLE);
4844                if (p_scb->socket_id[1] != -1)
4845                {
4846                    FD_CLR(p_scb->socket_id[1] , p_org_set);
4847                    shutdown(p_scb->socket_id[1], SHUT_RDWR);
4848                    close(p_scb->socket_id[1]);
4849
4850                    evt_param.chan_cb.app_id = (int) btif_hl_get_app_id(p_scb->channel_id);
4851                    memcpy(evt_param.chan_cb.bd_addr, p_scb->bd_addr, sizeof(BD_ADDR));
4852                    evt_param.chan_cb.channel_id = p_scb->channel_id;
4853                    evt_param.chan_cb.fd = p_scb->socket_id[0];
4854                    evt_param.chan_cb.mdep_cfg_index = (int ) p_scb->mdep_cfg_idx;
4855                    evt_param.chan_cb.cb_state = BTIF_HL_CHAN_CB_STATE_DISCONNECTED_PENDING;
4856                    len = sizeof(btif_hl_send_chan_state_cb_t);
4857                    status = btif_transfer_context (btif_hl_proc_cb_evt, BTIF_HL_SEND_DISCONNECTED_CB,
4858                                                    (char*) &evt_param, len, NULL);
4859                    ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
4860
4861
4862                }
4863            }
4864            p_scb = (btif_hl_soc_cb_t *)GKI_getnext((void *)p_scb );
4865            BTIF_TRACE_DEBUG1("while loop next p_scb=0x%x", p_scb);
4866        }
4867
4868        p_scb = (btif_hl_soc_cb_t *)GKI_getfirst((void *)&soc_queue);
4869        while (p_scb != NULL)
4870        {
4871            if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_IDLE)
4872            {
4873                p_dcb = BTIF_HL_GET_MDL_CB_PTR(p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx);
4874                BTIF_TRACE_DEBUG4("idle socket app_idx=%d mcl_id=%d, mdl_idx=%d p_dcb->in_use=%d",
4875                                  p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx, p_dcb->in_use);
4876                GKI_remove_from_queue((void *)&soc_queue, p_scb);
4877                btif_hl_free_buf((void **)&p_scb);
4878                p_dcb->p_scb = NULL;
4879                element_removed = TRUE;
4880            }
4881            BTIF_TRACE_DEBUG2("element_removed=%d p_scb=0x%x", element_removed, p_scb);
4882            if (element_removed)
4883            {
4884                element_removed = FALSE;
4885                p_scb = (btif_hl_soc_cb_t *)GKI_getfirst((void *)&soc_queue);
4886            }
4887            else
4888                p_scb = (btif_hl_soc_cb_t *)GKI_getnext((void *)p_scb );
4889
4890            BTIF_TRACE_DEBUG1("while loop p_scb=0x%x", p_scb);
4891        }
4892    }
4893    BTIF_TRACE_DEBUG1("leaving %s",__FUNCTION__);
4894}
4895/*******************************************************************************
4896**
4897** Function btif_hl_select_wakeup_callback
4898**
4899** Description Select wakup callback to add or close a socket
4900**
4901** Returns void
4902**
4903*******************************************************************************/
4904
4905void btif_hl_select_wakeup_callback( fd_set *p_org_set ,  int wakeup_signal){
4906    BTIF_TRACE_DEBUG2("entering %s wakeup_signal=0x%04x",__FUNCTION__, wakeup_signal);
4907
4908    if (wakeup_signal == btif_hl_signal_select_wakeup )
4909    {
4910        btif_hl_add_socket_to_set(p_org_set);
4911    }
4912    else if (wakeup_signal == btif_hl_signal_select_close_connected)
4913    {
4914        btif_hl_close_socket(p_org_set);
4915    }
4916    BTIF_TRACE_DEBUG1("leaving %s",__FUNCTION__);
4917}
4918
4919/*******************************************************************************
4920**
4921** Function btif_hl_select_monitor_callback
4922**
4923** Description Select monitor callback to check pending socket actions
4924**
4925** Returns void
4926**
4927*******************************************************************************/
4928void btif_hl_select_monitor_callback( fd_set *p_cur_set , fd_set *p_org_set){
4929    btif_hl_soc_cb_t      *p_scb = NULL;
4930    btif_hl_mdl_cb_t      *p_dcb = NULL;
4931    int r;
4932
4933    BTIF_TRACE_DEBUG1("entering %s",__FUNCTION__);
4934
4935    if (!GKI_queue_is_empty(&soc_queue))
4936    {
4937        p_scb = (btif_hl_soc_cb_t *)GKI_getfirst((void *)&soc_queue);
4938        BTIF_TRACE_DEBUG0(" GKI queue is not empty ");
4939        while (p_scb != NULL)
4940        {
4941            if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_W4_READ)
4942            {
4943                if (FD_ISSET(p_scb->socket_id[1], p_cur_set))
4944                {
4945                    BTIF_TRACE_DEBUG0("read data");
4946                    BTIF_TRACE_DEBUG0("state= BTIF_HL_SOC_STATE_W4_READ");
4947                    p_dcb = BTIF_HL_GET_MDL_CB_PTR(p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx);
4948                    if (p_dcb->p_tx_pkt)
4949                    {
4950                        BTIF_TRACE_ERROR1("Rcv new pkt but the last pkt is still not been sent tx_size=%d", p_dcb->tx_size);
4951                        btif_hl_free_buf((void **) &p_dcb->p_tx_pkt);
4952                    }
4953                    p_dcb->p_tx_pkt =  btif_hl_get_buf (p_dcb->mtu);
4954                    if (p_dcb )
4955                    {
4956                        //do
4957                        // {
4958                        //     r = recv(p_scb->socket_id[1], p_dcb->p_tx_pkt, p_dcb->mtu , MSG_DONTWAIT));
4959                        // } while (r == SOCKET_ERROR && errno == EINTR);
4960
4961                        if ((r = (int)recv(p_scb->socket_id[1], p_dcb->p_tx_pkt, p_dcb->mtu , MSG_DONTWAIT)) > 0)
4962                        {
4963                            BTIF_TRACE_DEBUG1("btif_hl_select_monitor_callback send data r =%d", r);
4964                            p_dcb->tx_size = r;
4965                            BTIF_TRACE_DEBUG1("btif_hl_select_monitor_callback send data tx_size=%d", p_dcb->tx_size );
4966                            BTA_HlSendData(p_dcb->mdl_handle, p_dcb->tx_size  );
4967                        }
4968
4969                        if (r <= 0 )
4970                        {
4971                            BTIF_TRACE_DEBUG1("btif_hl_select_monitor_callback  receive failed r=%d",r);
4972                            BTA_HlDchClose(p_dcb->mdl_handle );
4973                        }
4974                    }
4975                }
4976            }
4977            p_scb = (btif_hl_soc_cb_t *)GKI_getnext((void *)p_scb );
4978        }
4979    }
4980    else
4981    {
4982        BTIF_TRACE_DEBUG0("btif_hl_select_monitor_queue is empty");
4983    }
4984    BTIF_TRACE_DEBUG1("leaving %s",__FUNCTION__);
4985}
4986/*******************************************************************************
4987**
4988** Function btif_hl_select_wakeup_init
4989**
4990** Description select loop wakup init
4991**
4992** Returns int
4993**
4994*******************************************************************************/
4995static inline int btif_hl_select_wakeup_init(fd_set* set){
4996    BTIF_TRACE_DEBUG0("btif_hl_select_wakeup_init");
4997    if (socketpair(AF_UNIX, SOCK_STREAM, 0, signal_fds) < 0)
4998    {
4999        BTIF_TRACE_ERROR1("socketpair failed: %s", strerror(errno));
5000        return -1;
5001    }
5002
5003    BTIF_TRACE_DEBUG2("btif_hl_select_wakeup_init signal_fds[0]=%d signal_fds[1]=%d",signal_fds[0], signal_fds[1] );
5004    FD_SET(signal_fds[0], set);
5005
5006    return signal_fds[0];
5007}
5008
5009/*******************************************************************************
5010**
5011** Function btif_hl_select_wakeup
5012**
5013** Description send a signal to wakupo the select loop
5014**
5015** Returns int
5016**
5017*******************************************************************************/
5018static inline int btif_hl_select_wakeup(void){
5019    char sig_on = btif_hl_signal_select_wakeup;
5020    BTIF_TRACE_DEBUG0("btif_hl_select_wakeup");
5021    return send(signal_fds[1], &sig_on, sizeof(sig_on), 0);
5022}
5023
5024/*******************************************************************************
5025**
5026** Function btif_hl_select_close_connected
5027**
5028** Description send a signal to close a socket
5029**
5030** Returns int
5031**
5032*******************************************************************************/
5033static inline int btif_hl_select_close_connected(void){
5034    char sig_on = btif_hl_signal_select_close_connected;
5035    BTIF_TRACE_DEBUG0("btif_hl_select_close_connected");
5036    return send(signal_fds[1], &sig_on, sizeof(sig_on), 0);
5037}
5038
5039/*******************************************************************************
5040**
5041** Function btif_hl_close_select_thread
5042**
5043** Description send signal to close the thread and then close all signal FDs
5044**
5045** Returns int
5046**
5047*******************************************************************************/
5048static inline int btif_hl_close_select_thread(void)
5049{
5050    int result = 0;
5051    char sig_on = btif_hl_signal_select_exit;
5052    BTIF_TRACE_DEBUG0("btif_hl_signal_select_exit");
5053    result = send(signal_fds[1], &sig_on, sizeof(sig_on), 0);
5054    /* Wait for the select_thread_id to exit */
5055    if (select_thread_id != -1) {
5056        pthread_join(select_thread_id, NULL);
5057        select_thread_id = -1;
5058    }
5059   /* Cleanup signal sockets */
5060    if(signal_fds[0] != -1)
5061    {
5062        close(signal_fds[0]);
5063        signal_fds[0] = -1;
5064    }
5065    if(signal_fds[1] != -1)
5066    {
5067        close(signal_fds[1]);
5068        signal_fds[1] = -1;
5069    }
5070    return result;
5071}
5072
5073/*******************************************************************************
5074**
5075** Function btif_hl_select_wake_reset
5076**
5077** Description clear the received signal for the select loop
5078**
5079** Returns int
5080**
5081*******************************************************************************/
5082static inline int btif_hl_select_wake_reset(void){
5083    char sig_recv = 0;
5084
5085    BTIF_TRACE_DEBUG0("btif_hl_select_wake_reset");
5086    recv(signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL);
5087    return(int)sig_recv;
5088}
5089/*******************************************************************************
5090**
5091** Function btif_hl_select_wake_signaled
5092**
5093** Description check whether a fd is set or not
5094**
5095** Returns int
5096**
5097*******************************************************************************/
5098static inline int btif_hl_select_wake_signaled(fd_set* set){
5099    BTIF_TRACE_DEBUG0("btif_hl_select_wake_signaled");
5100    return FD_ISSET(signal_fds[0], set);
5101}
5102/*******************************************************************************
5103**
5104** Function btif_hl_thread_cleanup
5105**
5106** Description  shut down and clean up the select loop
5107**
5108** Returns void
5109**
5110*******************************************************************************/
5111static void btif_hl_thread_cleanup(){
5112    if (listen_s != -1)
5113        close(listen_s);
5114    if (connected_s != -1)
5115    {
5116        shutdown(connected_s, SHUT_RDWR);
5117        close(connected_s);
5118    }
5119    listen_s = connected_s = -1;
5120    BTIF_TRACE_DEBUG0("hl thread cleanup");
5121}
5122/*******************************************************************************
5123**
5124** Function btif_hl_select_thread
5125**
5126** Description the select loop
5127**
5128** Returns void
5129**
5130*******************************************************************************/
5131static void *btif_hl_select_thread(void *arg){
5132    fd_set org_set, curr_set;
5133    int r, max_curr_s, max_org_s;
5134
5135    BTIF_TRACE_DEBUG0("entered btif_hl_select_thread");
5136    FD_ZERO(&org_set);
5137    max_org_s = btif_hl_select_wakeup_init(&org_set);
5138    BTIF_TRACE_DEBUG1("max_s=%d ", max_org_s);
5139
5140    for (;;)
5141    {
5142        r = 0;
5143        BTIF_TRACE_DEBUG0("set curr_set = org_set ");
5144        curr_set = org_set;
5145        max_curr_s = max_org_s;
5146        int ret = select((max_curr_s + 1), &curr_set, NULL, NULL, NULL);
5147        BTIF_TRACE_DEBUG1("select unblocked ret=%d", ret);
5148        if (ret == -1)
5149        {
5150            BTIF_TRACE_DEBUG0("select() ret -1, exit the thread");
5151            btif_hl_thread_cleanup();
5152            select_thread_id = -1;
5153            return 0;
5154        }
5155        else if (ret)
5156        {
5157            BTIF_TRACE_DEBUG1("btif_hl_select_wake_signaled, signal ret=%d", ret);
5158            if (btif_hl_select_wake_signaled(&curr_set))
5159            {
5160                r = btif_hl_select_wake_reset();
5161                BTIF_TRACE_DEBUG1("btif_hl_select_wake_signaled, signal:%d", r);
5162                if (r == btif_hl_signal_select_wakeup || r == btif_hl_signal_select_close_connected )
5163                {
5164                    btif_hl_select_wakeup_callback(&org_set, r);
5165                }
5166                else if( r == btif_hl_signal_select_exit)
5167                {
5168                    btif_hl_thread_cleanup();
5169                    BTIF_TRACE_DEBUG0("Exit hl_select_thread for btif_hl_signal_select_exit");
5170                    return 0;
5171                }
5172            }
5173
5174            btif_hl_select_monitor_callback(&curr_set, &org_set);
5175            max_org_s = btif_hl_update_maxfd(max_org_s);
5176        }
5177        else
5178            BTIF_TRACE_DEBUG1("no data, select ret: %d\n", ret);
5179    }
5180    BTIF_TRACE_DEBUG0("leaving hl_select_thread");
5181    return 0;
5182}
5183
5184/*******************************************************************************
5185**
5186** Function create_thread
5187**
5188** Description creat a select loop
5189**
5190** Returns pthread_t
5191**
5192*******************************************************************************/
5193static inline pthread_t create_thread(void *(*start_routine)(void *), void * arg){
5194    BTIF_TRACE_DEBUG0("create_thread: entered");
5195    pthread_attr_t thread_attr;
5196
5197    pthread_attr_init(&thread_attr);
5198    pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
5199    pthread_t thread_id = -1;
5200    if ( pthread_create(&thread_id, &thread_attr, start_routine, arg)!=0 )
5201    {
5202        BTIF_TRACE_ERROR1("pthread_create : %s", strerror(errno));
5203        return -1;
5204    }
5205    BTIF_TRACE_DEBUG0("create_thread: thread created successfully");
5206    return thread_id;
5207}
5208
5209/*******************************************************************************
5210**
5211** Function         btif_hl_soc_thread_init
5212**
5213** Description      HL select loop init function.
5214**
5215** Returns          void
5216**
5217*******************************************************************************/
5218void btif_hl_soc_thread_init(void){
5219    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
5220    GKI_init_q(&soc_queue);
5221    select_thread_id = create_thread(btif_hl_select_thread, NULL);
5222}
5223/*******************************************************************************
5224**
5225** Function btif_hl_load_mdl_config
5226**
5227** Description load the MDL configuation from the application control block
5228**
5229** Returns BOOLEAN
5230**
5231*******************************************************************************/
5232BOOLEAN btif_hl_load_mdl_config (UINT8 app_id, UINT8 buffer_size,
5233                                 tBTA_HL_MDL_CFG *p_mdl_buf ){
5234    UINT8 app_idx;
5235    BOOLEAN result = FALSE;
5236    btif_hl_app_cb_t          *p_acb;
5237    tBTA_HL_MDL_CFG *p;
5238    int i;
5239    BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
5240
5241    if (btif_hl_find_app_idx(app_id, &app_idx))
5242    {
5243        p_acb  = BTIF_HL_GET_APP_CB_PTR(app_idx);
5244        for (i=0, p=p_mdl_buf; i<buffer_size; i++, p++)
5245        {
5246            memcpy(p, &p_acb->mdl_cfg[i].base, sizeof(tBTA_HL_MDL_CFG));
5247        }
5248        result = TRUE;
5249    }
5250
5251    BTIF_TRACE_DEBUG1("result=%d", result);
5252    return result;
5253}
5254