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