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