void bta_hf_client_send_at_clip(BOOLEAN activate)
{
    char *buf;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    if (activate)
        buf = "AT+CLIP=1\r";
    else
        buf = "AT+CLIP=0\r";

    bta_hf_client_send_at(BTA_HF_CLIENT_AT_CLIP, buf, strlen(buf));
}
static void *sock_poll_thread(void *arg)
{
    struct pollfd pfds[MAX_POLL];
    memset(pfds, 0, sizeof(pfds));
    int h = (int)arg;
    for(;;)
    {
        prepare_poll_fds(h, pfds);
        int ret = poll(pfds, ts[h].poll_count, -1);
        if(ret == -1)
        {
            APPL_TRACE_ERROR2("poll ret -1, exit the thread, errno:%d, err:%s", errno, strerror(errno));
            break;
        }
        if(ret != 0)
        {
            int need_process_data_fd = TRUE;
            if(pfds[0].revents) //cmd fd always is the first one
            {
                asrt(pfds[0].fd == ts[h].cmd_fdr);
                if(!process_cmd_sock(h))
                {
                    APPL_TRACE_DEBUG1("h:%d, process_cmd_sock return false, exit...", h);
                    break;
                }
                if(ret == 1)
                    need_process_data_fd = FALSE;
                else ret--; //exclude the cmd fd
            }
            if(need_process_data_fd)
                process_data_sock(h, pfds, ret);
        }
        else {APPL_TRACE_DEBUG1("no data, select ret: %d", ret)};
    }
    ts[h].thread_id = -1;
    APPL_TRACE_DEBUG1("socket poll thread exiting, h:%d", h);
    return 0;
}
void bta_av_conn_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
{
    tBTA_AV_STR_MSG     *p_msg;
    UINT16  evt = 0;
    tBTA_AV_SCB *p_scb = NULL;

#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
    if (event == BTA_AR_AVDT_CONN_EVT ||
        event == AVDT_CONNECT_IND_EVT || event == AVDT_DISCONNECT_IND_EVT)
#else
    if (event == AVDT_CONNECT_IND_EVT || event == AVDT_DISCONNECT_IND_EVT)
#endif
    {
        evt = BTA_AV_SIG_CHG_EVT;
        if(AVDT_DISCONNECT_IND_EVT == event)
            p_scb = bta_av_addr_to_scb(bd_addr);
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
        else if (AVDT_CONNECT_IND_EVT == event)
        {
            APPL_TRACE_DEBUG1("CONN_IND is ACP:%d", p_data->hdr.err_param);
        }
#endif

        if (/*((p_scb && (p_scb->role & BTA_AV_ROLE_AD_ACP)) ||

            //(AVDT_CONNECT_IND_EVT == event && AVDT_ACP == p_data->hdr.err_param))

            (AVDT_CONNECT_IND_EVT == event))&& */
            (p_msg = (tBTA_AV_STR_MSG *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_STR_MSG)))) != NULL)
        {
            p_msg->hdr.event = evt;
            p_msg->hdr.layer_specific = event;
            p_msg->hdr.offset = p_data->hdr.err_param;
            bdcpy(p_msg->bd_addr, bd_addr);
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
            if(p_scb)
            {
                APPL_TRACE_DEBUG2("scb hndl x%x, role x%x", p_scb->hndl, p_scb->role);
            }
#endif
            APPL_TRACE_DEBUG6("conn_cback bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
                          bd_addr[0], bd_addr[1],
                          bd_addr[2], bd_addr[3],
                          bd_addr[4], bd_addr[5]);
            bta_sys_sendmsg(p_msg);
        }
    }

}
void bta_hf_client_send_at_cnum(void)
{
    char *buf;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    if (!service_availability)
    {
        APPL_TRACE_DEBUG0("Skip AT+CNUM no Service");
        return;
    }
    buf = "AT+CNUM\r";

    bta_hf_client_send_at(BTA_HF_CLIENT_AT_CNUM, buf, strlen(buf));
}
static void bta_hf_client_start_at_hold_timer(void)
{
    TIMER_LIST_ENT *timer = &bta_hf_client_cb.scb.at_cb.hold_timer;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    if (bta_hf_client_cb.scb.at_cb.hold_timer_on)
    {
        bta_sys_stop_timer (timer);
    }

    timer->p_cback = (TIMER_CBACK*)&bta_hf_client_at_hold_timer_cback;
    bta_sys_start_timer(timer, 0, BTA_HF_CLIENT_AT_HOLD_TIMEOUT);
    bta_hf_client_cb.scb.at_cb.hold_timer_on = TRUE;
}
void bta_hf_client_send_at_brsf(void)
{
    char buf[BTA_HF_CLIENT_AT_MAX_LEN];
    int at_len;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    at_len = snprintf(buf, sizeof(buf), "AT+BRSF=%lu\r", bta_hf_client_cb.scb.features);
    if (at_len < 0)
    {
        APPL_TRACE_ERROR0("HFPClient: AT command Framing error");
        return;
    }

    bta_hf_client_send_at(BTA_HF_CLIENT_AT_BRSF , buf, at_len);
}
void bta_hf_client_send_at_binp(UINT32 action)
{
    char buf[BTA_HF_CLIENT_AT_MAX_LEN];
    int at_len;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    at_len = snprintf(buf, sizeof(buf), "AT+BINP=%lu\r", action);

    if (at_len < 0)
    {
        APPL_TRACE_ERROR0("HFPClient: AT command Framing error");
        return;
    }
    bta_hf_client_send_at(BTA_HF_CLIENT_AT_BINP, buf, at_len);
}
void bta_hf_client_send_at_vts(char code)
{
    char buf[BTA_HF_CLIENT_AT_MAX_LEN];
    int at_len;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    at_len = snprintf(buf, sizeof(buf), "AT+VTS=%c\r", code);

    if (at_len < 0)
    {
        APPL_TRACE_ERROR0("HFPClient: AT command Framing error");
        return;
    }
    bta_hf_client_send_at(BTA_HF_CLIENT_AT_VTS, buf, at_len);
}
/******************************************************************************
**
** Function         bte_main_enable
**
** Description      BTE MAIN API - Creates all the BTE tasks. Should be called
**                  part of the Bluetooth stack enable sequence
**
** Returns          None
**
******************************************************************************/
void bte_main_enable()
{
    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    /* Initialize BTE control block */
    BTE_Init();

    lpm_enabled = FALSE;

    GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,
                    (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),
                    sizeof(bte_btu_stack));

    bte_hci_enable();
		    
    GKI_run(0);
}
static inline int create_server_socket(const char* name)
{
    int s = socket(AF_LOCAL, SOCK_STREAM, 0);
    APPL_TRACE_DEBUG1("covert name to android abstract name:%s", name);
    if(socket_local_server_bind(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT) >= 0)
    {
        if(listen(s, 5) == 0)
        {
            APPL_TRACE_DEBUG2("listen to local socket:%s, fd:%d", name, s);
            return s;
        }
        else APPL_TRACE_ERROR3("listen to local socket:%s, fd:%d failed, errno:%d", name, s, errno);
    }
    else APPL_TRACE_ERROR3("create local socket:%s fd:%d, failed, errno:%d", name, s, errno);
    close(s);
    return -1;
}
void bta_hf_client_send_at_bac(void)
{
    char *buf;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    if (bta_hf_client_cb.msbc_enabled)
    {
        buf = "AT+BAC=1,2\r";
    }
    else
    {
        buf = "AT+BAC=1\r";
    }

    bta_hf_client_send_at(BTA_HF_CLIENT_AT_BAC, buf, strlen(buf));
}
static void bta_hf_client_at_parse_start(void)
{
    char *buf = bta_hf_client_cb.scb.at_cb.buf;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

#ifdef BTA_HF_CLIENT_AT_DUMP
    bta_hf_client_dump_at();
#endif

    while(*buf != '\0')
    {
        int i;
        char *tmp = NULL;

        for(i = 0; i < bta_hf_client_psraser_cb_count; i++)
        {
            tmp = bta_hf_client_parser_cb[i](buf);
            if (tmp == NULL)
            {
                APPL_TRACE_ERROR0("HFPCient: AT event/reply parsing failed, skipping");
                tmp = bta_hf_client_skip_unknown(buf);
                break;
            }

            /* matched or unknown skipped, if unknown failed tmp is NULL so
               this is also handled */
            if (tmp != buf)
            {
                buf = tmp;
                break;
            }
        }

        /* could not skip unknown (received garbage?)... disconnect */
        if (tmp == NULL)
        {
            APPL_TRACE_ERROR0("HFPCient: could not skip unknown AT event, disconnecting");
            bta_hf_client_at_reset();
            bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, NULL);
            return;
        }

        buf = tmp;
    }
}
Exemple #13
0
/*******************************************************************************
**
** Function         bta_ag_resume_open
**
** Description      Resume opening process.
**
**
** Returns          void
**
*******************************************************************************/
void bta_ag_resume_open (tBTA_AG_SCB *p_scb)
{
    if (p_scb)
    {
        APPL_TRACE_DEBUG1 ("bta_ag_resume_open, Handle(%d)", bta_ag_scb_to_idx(p_scb));

        /* resume opening process.  */
        if (p_scb->state == BTA_AG_INIT_ST)
        {
            p_scb->state = BTA_AG_OPENING_ST;
            bta_ag_start_open (p_scb, NULL);
        }
    }
    else
    {
        APPL_TRACE_ERROR0 ("bta_ag_resume_open, Null p_scb");
    }
}
void bta_hf_client_send_at_cops(BOOLEAN query)
{
    char *buf;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    if (!service_availability)
    {
        APPL_TRACE_DEBUG0("Skip AT+COPS no service");
        return;
    }
    if (query)
        buf = "AT+COPS?\r";
    else
        buf = "AT+COPS=3,0\r";

    bta_hf_client_send_at(BTA_HF_CLIENT_AT_COPS, buf, strlen(buf));
}
static void bta_hf_client_send_queued_at(void)
{
    tBTA_HF_CLIENT_AT_QCMD *cur = bta_hf_client_cb.scb.at_cb.queued_cmd;
    tBTA_HF_CLIENT_AT_QCMD *next;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    if (cur != NULL)
    {
        next = cur->next;

        bta_hf_client_send_at(cur->cmd, cur->buf, cur->buf_len);

        GKI_freebuf(cur);

        bta_hf_client_cb.scb.at_cb.queued_cmd = next;
    }
}
Exemple #16
0
/*******************************************************************************
 **
 ** Function         bta_av_co_audio_init
 **
 ** Description      This callout function is executed by AV when it is
 **                  started by calling BTA_AvRegister().  This function can be
 **                  used by the phone to initialize audio paths or for other
 **                  initialization purposes.
 **
 **
 ** Returns          Stream codec and content protection capabilities info.
 **
 *******************************************************************************/
BOOLEAN bta_av_co_audio_init(UINT8 *p_codec_type, UINT8 *p_codec_info, UINT8 *p_num_protect,
        UINT8 *p_protect_info, UINT8 index)
{
    FUNC_TRACE();

    APPL_TRACE_DEBUG1("bta_av_co_audio_init: %d", index);

#if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
    {
        UINT8 *p = p_protect_info;

        /* Content protection info - support SCMS-T */
        *p_num_protect = 1;
        *p++ = BTA_AV_CP_LOSC;
        UINT16_TO_STREAM(p, BTA_AV_CP_SCMS_T_ID);

    }
#else
    /* By default - no content protection info */
    *p_num_protect = 0;
    *p_protect_info = 0;
#endif

    /* reset remote preference through setconfig */
    bta_av_co_cb.codec_cfg_setconfig.id = BTIF_AV_CODEC_NONE;

    switch (index)
    {
    case BTIF_SV_AV_AA_SBC_INDEX:
        /* Set up for SBC codec */
        *p_codec_type = BTA_AV_CODEC_SBC;

        /* This should not fail because we are using constants for parameters */
        A2D_BldSbcInfo(AVDT_MEDIA_AUDIO, (tA2D_SBC_CIE *) &bta_av_co_sbc_caps, p_codec_info);

        /* Codec is valid */
        return TRUE;


    default:
        /* Not valid */
        return FALSE;
    }
}
void bta_hf_client_send_at_chld(char cmd, UINT32 idx)
{
    char buf[BTA_HF_CLIENT_AT_MAX_LEN];
    int at_len;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    if (idx > 0)
        at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c%lu\r", cmd, idx);
    else
        at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c\r", cmd);

    if (at_len < 0)
    {
        APPL_TRACE_ERROR0("HFPClient: AT command Framing error");
        return;
    }
    bta_hf_client_send_at(BTA_HF_CLIENT_AT_CHLD, buf, at_len);
}
/*******************************************************************************
**
** Function         bta_hf_client_sco_conn_open
**
** Description
**
**
** Returns          void
**
*******************************************************************************/
void bta_hf_client_sco_conn_open(tBTA_HF_CLIENT_DATA *p_data)
{
    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    bta_hf_client_sco_event(BTA_HF_CLIENT_SCO_CONN_OPEN_E);

    bta_sys_sco_open(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);

    if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_MSBC)
    {
        bta_hf_client_cback_sco(BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT);
    }
    else
    {
        bta_hf_client_cback_sco(BTA_HF_CLIENT_AUDIO_OPEN_EVT);
    }

    bta_hf_client_cb.scb.retry_with_sco_only = FALSE;
}
static void bta_hf_client_handle_ok()
{
    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    bta_hf_client_stop_at_resp_timer();

    if (!bta_hf_client_cb.scb.svc_conn)
    {
        bta_hf_client_slc_seq(FALSE);
        return;
    }

    switch(bta_hf_client_cb.scb.at_cb.current_cmd)
    {
        case BTA_HF_CLIENT_AT_BIA:
        case BTA_HF_CLIENT_AT_BCC:
            break;
        case BTA_HF_CLIENT_AT_BCS:
            bta_hf_client_start_at_hold_timer();
            bta_hf_client_cb.scb.at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
            return;
        case BTA_HF_CLIENT_AT_CLIP: //last cmd is post slc seq
            if (bta_hf_client_cb.scb.send_at_reply == FALSE)
            {
                bta_hf_client_cb.scb.send_at_reply = TRUE;
            }
            break;
        case BTA_HF_CLIENT_AT_NONE:
            bta_hf_client_stop_at_hold_timer();
            break;
        default:
            if (bta_hf_client_cb.scb.send_at_reply)
            {
                bta_hf_client_at_result(BTA_HF_CLIENT_AT_RESULT_OK, 0);
            }
            break;
    }

    bta_hf_client_cb.scb.at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;

    bta_hf_client_send_queued_at();
}
void bta_hf_client_send_at_cind(BOOLEAN status)
{
    char *buf;
    tBTA_HF_CLIENT_AT_CMD cmd;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    if (status)
    {
        buf = "AT+CIND?\r";
        cmd = BTA_HF_CLIENT_AT_CIND_STATUS;
    }
    else
    {
        buf = "AT+CIND=?\r";
        cmd = BTA_HF_CLIENT_AT_CIND;
    }

    bta_hf_client_send_at(cmd, buf, strlen(buf));
}
/*******************************************************************************
**
** Function         bta_av_restore_switch
**
** Description      assume that the caller of this function already makes
**                  sure that there's only one ACL connection left
**
** Returns          void
**
*******************************************************************************/
void bta_av_restore_switch (void)
{
    tBTA_AV_CB   *p_cb = &bta_av_cb;
    int     i;
    UINT8   mask;

    APPL_TRACE_DEBUG1("reg_audio: 0x%x",bta_av_cb.reg_audio);
    for(i=0; i<BTA_AV_NUM_STRS; i++)
    {
        mask = BTA_AV_HNDL_TO_MSK(i);
        if (p_cb->conn_audio == mask)
        {
            if (p_cb->p_scb[i])
            {
                bta_sys_set_policy(BTA_ID_AV, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_cb->p_scb[i]->peer_addr);
            }
            break;
        }
    }
}
int btsock_thread_init()
{
    static int initialized;
    APPL_TRACE_DEBUG1("in initialized:%d", initialized);
    if(!initialized)
    {
        initialized = 1;
        init_slot_lock(&thread_slot_lock);
        int h;
        for(h = 0; h < MAX_THREAD; h++)
        {
            ts[h].cmd_fdr = ts[h].cmd_fdw = -1;
            ts[h].used = 0;
            ts[h].thread_id = -1;
            ts[h].poll_count = 0;
            ts[h].callback = NULL;
            ts[h].cmd_callback = NULL;
        }
    }
    return TRUE;
}
Exemple #23
0
/*******************************************************************************
**
** Function         bta_ag_scb_by_idx
**
** Description      Given an scb index return pointer to scb.
**
**
** Returns          Pointer to scb or NULL if not allocated.
**
*******************************************************************************/
tBTA_AG_SCB *bta_ag_scb_by_idx(UINT16 idx)
{
    tBTA_AG_SCB     *p_scb;

    /* verify index */
    if (idx > 0 && idx <= BTA_AG_NUM_SCB)
    {
        p_scb = &bta_ag_cb.scb[idx - 1];
        if (!p_scb->in_use)
        {
            p_scb = NULL;
            APPL_TRACE_WARNING1("ag scb idx %d not allocated", idx);
        }
    }
    else
    {
        p_scb = NULL;
        APPL_TRACE_DEBUG1("ag scb idx %d out of range", idx);
    }
    return p_scb;
}
/*******************************************************************************
**
** Function         bta_ag_del_records
**
** Description      Delete SDP records for any registered services.
**
**
** Returns          void
**
*******************************************************************************/
void bta_ag_del_records(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
{
    tBTA_AG_SCB         *p = &bta_ag_cb.scb[0];
    tBTA_SERVICE_MASK   services;
    tBTA_SERVICE_MASK   others = 0;
    int                 i;

    /* get services of all other registered servers */
    for (i = 0; i < BTA_AG_NUM_IDX; i++, p++)
    {
        if (p_scb == p)
        {
            continue;
        }

        if (p->in_use && p->dealloc == FALSE)
        {
            others |= p->reg_services;
        }
    }

    others >>= BTA_HSP_SERVICE_ID;
    services = p_scb->reg_services >> BTA_HSP_SERVICE_ID;
    for (i = 0; i < BTA_AG_NUM_IDX && services != 0; i++, services >>= 1, others >>= 1)
    {
        /* if service registered for this scb and not registered for any other scb */
        if (((services & 1) == 1) && ((others & 1) == 0))
        {
            APPL_TRACE_DEBUG1("bta_ag_del_records %d", i);
            if (bta_ag_cb.profile[i].sdp_handle != 0)
            {
                SDP_DeleteRecord(bta_ag_cb.profile[i].sdp_handle);
                bta_ag_cb.profile[i].sdp_handle = 0;
            }
            BTM_FreeSCN(bta_ag_cb.profile[i].scn);
            BTM_SecClrService(bta_ag_sec_id[i]);
            bta_sys_remove_uuid(bta_ag_uuid[i]);
        }
    }
}
static void  on_srv_rfc_listen_started(tBTA_JV_RFCOMM_START *p_start, uint32_t id)
{
    lock_slot(&slot_lock);
    rfc_slot_t* rs = find_rfc_slot_by_id(id);
    if(rs)
    {
        if (p_start->status != BTA_JV_SUCCESS)
            cleanup_rfc_slot(rs);
        else
        {
            rs->rfc_handle = p_start->handle;

            if(!send_app_scn(rs))
            {
                //closed
                APPL_TRACE_DEBUG1("send_app_scn() failed, close rs->id:%d", rs->id);
                cleanup_rfc_slot(rs);
            }
        }
    }
    unlock_slot(&slot_lock);
}
void bta_hf_client_send_at_atd(char *number, UINT32 memory)
{
    char buf[BTA_HF_CLIENT_AT_MAX_LEN];
    int at_len;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    if (number[0] != '\0')
    {
        at_len = snprintf(buf, sizeof(buf), "ATD%s;\r", number);
    }
    else
    {
        at_len = snprintf(buf, sizeof(buf), "ATD>%lu;\r", memory);
    }

    if (at_len < 0)
    {
        APPL_TRACE_ERROR0("HFPClient: AT command Framing error");
        return;
    }
    bta_hf_client_send_at(BTA_HF_CLIENT_AT_ATD, buf, at_len);
}
void bta_hf_client_send_at_btrh(BOOLEAN query, UINT32 val)
{
    char buf[BTA_HF_CLIENT_AT_MAX_LEN];
    int at_len;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    if (query == TRUE)
    {
        at_len = snprintf(buf, sizeof(buf), "AT+BTRH?\r");
    }
    else
    {
        at_len = snprintf(buf, sizeof(buf), "AT+BTRH=%lu\r", val);
    }

    if (at_len < 0)
    {
        APPL_TRACE_ERROR0("HFPClient: AT command Framing error");
        return;
    }
    bta_hf_client_send_at(BTA_HF_CLIENT_AT_BTRH, buf, at_len);
}
/*******************************************************************************
**
** Function         bta_pan_scb_alloc
**
** Description      Allocate a PAN server control block.
**
**
** Returns          pointer to the scb, or NULL if none could be allocated.
**
*******************************************************************************/
tBTA_PAN_SCB *bta_pan_scb_alloc(void)
{
    tBTA_PAN_SCB     *p_scb = &bta_pan_cb.scb[0];
    int             i;

    for (i = 0; i < BTA_PAN_NUM_CONN; i++, p_scb++)
    {
        if (!p_scb->in_use)
        {
            p_scb->in_use = TRUE;
            APPL_TRACE_DEBUG1("bta_pan_scb_alloc %d", i);
            break;
        }
    }

    if (i == BTA_PAN_NUM_CONN)
    {
        /* out of scbs */
        p_scb = NULL;
        APPL_TRACE_WARNING0("Out of scbs");
    }
    return p_scb;
}
Exemple #29
0
/*******************************************************************************
**
** Function         bta_ag_scb_dealloc
**
** Description      Deallocate a service control block.
**
**
** Returns          void
**
*******************************************************************************/
void bta_ag_scb_dealloc(tBTA_AG_SCB *p_scb)
{
    UINT8   idx;
    BOOLEAN allocated = FALSE;

    APPL_TRACE_DEBUG1("bta_ag_scb_dealloc %d", bta_ag_scb_to_idx(p_scb));

    /* stop timers */
    bta_sys_stop_timer(&p_scb->act_timer);
#if (BTM_WBS_INCLUDED == TRUE)
    bta_sys_stop_timer(&p_scb->cn_timer);
#endif

    /* initialize control block */
    memset(p_scb, 0, sizeof(tBTA_AG_SCB));
    p_scb->sco_idx = BTM_INVALID_SCO_INDEX;

    /* If all scbs are deallocated, callback with disable event */
    if (!bta_sys_is_register (BTA_ID_AG))
    {
        for (idx = 0; idx < BTA_AG_NUM_SCB; idx++)
        {
            if (bta_ag_cb.scb[idx].in_use)
            {
                allocated = TRUE;
                break;
            }
        }

        if (!allocated)
        {
            (*bta_ag_cb.p_cback)(BTA_AG_DISABLE_EVT, NULL);
        }
    }

}
/*******************************************************************************
**
** Function         bta_gattc_hdl_event
**
** Description      GATT client main event handling function.
**
**
** Returns          void
**
*******************************************************************************/
BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
{
    tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
    tBTA_GATTC_CLCB *p_clcb = NULL;
    tBTA_GATTC_RCB      *p_clreg;
#if BTA_GATT_DEBUG == TRUE
    APPL_TRACE_DEBUG1("bta_gattc_hdl_event: Event [%s]", gattc_evt_code(p_msg->event));
#endif
    switch (p_msg->event)
    {
        case BTA_GATTC_API_DISABLE_EVT:
            bta_gattc_disable(p_cb);
            break;

        case BTA_GATTC_API_REG_EVT:
            bta_gattc_register(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;

        case BTA_GATTC_INT_START_IF_EVT:
            bta_gattc_start_if(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;

        case BTA_GATTC_API_DEREG_EVT:
            p_clreg = bta_gattc_cl_get_regcb(((tBTA_GATTC_DATA *)p_msg)->api_dereg.client_if);
            bta_gattc_deregister(p_cb, p_clreg);
            break;

        case BTA_GATTC_API_OPEN_EVT:
            bta_gattc_process_api_open(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;

        case BTA_GATTC_API_CANCEL_OPEN_EVT:
            bta_gattc_process_api_open_cancel(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;

        case BTA_GATTC_API_REFRESH_EVT:
            bta_gattc_process_api_refresh(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;

#if BLE_INCLUDED == TRUE
        case BTA_GATTC_API_LISTEN_EVT:
            bta_gattc_listen(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;
        case BTA_GATTC_API_BROADCAST_EVT:
            bta_gattc_broadcast(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;
#endif

        case BTA_GATTC_ENC_CMPL_EVT:
            bta_gattc_process_enc_cmpl(p_cb, (tBTA_GATTC_DATA *) p_msg);
            break;

        default:
            if (p_msg->event == BTA_GATTC_INT_CONN_EVT)
                p_clcb = bta_gattc_find_int_conn_clcb((tBTA_GATTC_DATA *) p_msg);
            else if (p_msg->event == BTA_GATTC_INT_DISCONN_EVT)
                p_clcb = bta_gattc_find_int_disconn_clcb((tBTA_GATTC_DATA *) p_msg);
            else
                p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->layer_specific);

            if (p_clcb != NULL)
            {
                bta_gattc_sm_execute(p_clcb, p_msg->event, (tBTA_GATTC_DATA *) p_msg);
            }
            else
            {
                APPL_TRACE_DEBUG1("Ignore unknown conn ID: %d", p_msg->layer_specific);
            }

            break;
    }


    return(TRUE);
}