/*******************************************************************************
**
** Function         bta_gattc_clcb_dealloc
**
** Description      Deallocte a clcb
**
** Returns          pointer to the clcb
**
*******************************************************************************/
void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb)
{
    tBTA_GATTC_SERV     *p_srcb = NULL;

    if (p_clcb)
    {
        p_srcb = p_clcb->p_srcb;
        if (p_srcb->num_clcb)
            p_srcb->num_clcb --;

        if (p_clcb->p_rcb->num_clcb)
            p_clcb->p_rcb->num_clcb --;

        /* if the srcb is no longer needed, reset the state */
        if ( p_srcb->num_clcb == 0)
        {
            p_srcb->connected = FALSE;
            p_srcb->state = BTA_GATTC_SERV_IDLE;
            p_srcb->mtu = 0;
        }

        utl_freebuf((void **)&p_clcb->p_q_cmd);

        memset(p_clcb, 0, sizeof(tBTA_GATTC_CLCB));
    }
    else
    {
        APPL_TRACE_ERROR("bta_gattc_clcb_dealloc p_clcb=NULL");
    }
}
Пример #2
0
/*******************************************************************************
**
** Function         bta_hh_di_sdp_cback
**
** Description      SDP DI callback function.
**
** Returns          void
**
*******************************************************************************/
static void bta_hh_di_sdp_cback(UINT16 result)
{
    tBTA_HH_DEV_CB     *p_cb = bta_hh_cb.p_cur;
    tBTA_HH_STATUS         status = BTA_HH_ERR_SDP;
    tSDP_DI_GET_RECORD  di_rec;
    tHID_STATUS ret;
#if BTA_HH_DEBUG
    APPL_TRACE_EVENT("bta_hh_di_sdp_cback: p_cb: %d result 0x%02x", p_cb, result);
#endif

    /* if DI record does not exist on remote device, vendor_id in tBTA_HH_DEV_DSCP_INFO will be
         * set to 0xffff and we will allow the connection to go through. Spec mandates that DI
         * record be set, but many HID devices do not set this. So for IOP purposes, we allow the
         * connection to go through and update the DI record to invalid DI entry.*/
    if (((result == SDP_SUCCESS) || (result == SDP_NO_RECS_MATCH)) && (p_cb != NULL))
    {
        if(result == SDP_SUCCESS && SDP_GetNumDiRecords(bta_hh_cb.p_disc_db) != 0)
        {
            /* always update information with primary DI record */
            if (SDP_GetDiRecord(1, &di_rec, bta_hh_cb.p_disc_db) == SDP_SUCCESS)
            {
                bta_hh_update_di_info(p_cb, di_rec.rec.vendor, di_rec.rec.product, di_rec.rec.version, 0);
            }

        }
        else /* no DI recrod available */
        {
            bta_hh_update_di_info(p_cb, BTA_HH_VENDOR_ID_INVALID, 0, 0, 0);
        }

        if ((ret = HID_HostGetSDPRecord(p_cb->addr,
                                 bta_hh_cb.p_disc_db,
                                 p_bta_hh_cfg->sdp_db_size,
                                 bta_hh_sdp_cback)) == HID_SUCCESS)
        {
            status = BTA_HH_OK;
        }
        else
        {
#if BTA_HH_DEBUG
            APPL_TRACE_DEBUG ("bta_hh_di_sdp_cback:  HID_HostGetSDPRecord failed: Status 0x%2x",
                               ret);
#endif
        }
    }


    if (status != BTA_HH_OK)
    {
        utl_freebuf((void **)&bta_hh_cb.p_disc_db);
        /* send SDP_CMPL_EVT into state machine */
        bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA *)&status);
    }
    return;

}
/*******************************************************************************
**
** Function         bta_gattc_srcb_alloc
**
** Description      allocate server cache control block
**
** Returns          pointer to the server cache.
**
*******************************************************************************/
tBTA_GATTC_SERV * bta_gattc_srcb_alloc(BD_ADDR bda)
{
    tBTA_GATTC_SERV *p_tcb = &bta_gattc_cb.known_server[0],
                             *p_recycle = NULL;
    BOOLEAN         found = FALSE;
    UINT8           i;

    for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_tcb ++)
    {
        if (!p_tcb->in_use)
        {
            found = TRUE;
            break;
        }
        else if (!p_tcb->connected)
        {
            p_recycle = p_tcb;
        }
    }

    /* if not found, try to recycle one known device */
    if (!found && !p_recycle)
        p_tcb = NULL;
    else if (!found && p_recycle)
        p_tcb = p_recycle;

    if (p_tcb != NULL)
    {
        while (!GKI_queue_is_empty(&p_tcb->cache_buffer))
            GKI_freebuf (GKI_dequeue (&p_tcb->cache_buffer));

        utl_freebuf((void **)&p_tcb->p_srvc_list);
        memset(p_tcb, 0 , sizeof(tBTA_GATTC_SERV));

        p_tcb->in_use = TRUE;
        bdcpy(p_tcb->server_bda, bda);
    }
    return p_tcb;
}
Пример #4
0
/*******************************************************************************
**
** Function         bta_hh_start_sdp
**
** Description      Start SDP service search, and obtain necessary SDP records.
**                  Only one SDP service search request is allowed at the same
**                  time. For every BTA_HhOpen API call, do SDP first unless SDP
**                  has been done previously.
**
** Returns          void
**
*******************************************************************************/
void bta_hh_start_sdp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
{
    tBTA_HH_STATUS          status = BTA_HH_ERR_SDP;
    UINT8                   hdl;

    p_cb->sec_mask  = p_data->api_conn.sec_mask;
    p_cb->mode      = p_data->api_conn.mode;
    bta_hh_cb.p_cur = p_cb;

#if (BTA_HH_LE_INCLUDED == TRUE)
    if (bta_hh_is_le_device(p_cb, p_data->api_conn.bd_addr))
    {
        bta_hh_le_open_conn(p_cb, p_data->api_conn.bd_addr);
        return;
    }
#endif

    /* if previously virtually cabled device, skip SDP */
    if (p_cb->app_id)
    {
        status = BTA_HH_OK;
#if BTA_HH_DEBUG
        APPL_TRACE_DEBUG("bta_hh_start_sdp:: skip SDP for known devices");
#endif
        if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE)
        {
            if (HID_HostAddDev (p_cb->addr, p_cb->attr_mask, &hdl) \
                == HID_SUCCESS)
            {
                /* update device CB with newly register device handle */
                bta_hh_add_device_to_list(p_cb,  hdl, p_cb->attr_mask, NULL,
                                          p_cb->sub_class,
                                          p_cb->dscp_info.ssr_max_latency,
                                          p_cb->dscp_info.ssr_min_tout,
                                          p_cb->app_id);
                /* update cb_index[] map */
                bta_hh_cb.cb_index[hdl] = p_cb->index;
            }
            else
                status = BTA_HH_ERR_NO_RES;
        }
        bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA *)&status);

        return;
    }
    /* GetSDPRecord. at one time only one SDP precedure can be active */
    else if (!bta_hh_cb.p_disc_db)
    {
        bta_hh_cb.p_disc_db = (tSDP_DISCOVERY_DB *) GKI_getbuf(p_bta_hh_cfg->sdp_db_size);

        if (bta_hh_cb.p_disc_db == NULL)
        {
            status = BTA_HH_ERR_NO_RES;
        }
        else
        {
            bta_hh_cb.p_cur = p_cb;
            /* do DI discovery first */
            if (SDP_DiDiscover(p_data->api_conn.bd_addr,
                                         bta_hh_cb.p_disc_db,
                                         p_bta_hh_cfg->sdp_db_size,
                                         bta_hh_di_sdp_cback) != SDP_SUCCESS)
            {
#if BTA_HH_DEBUG
                APPL_TRACE_DEBUG ("bta_hh_start_sdp:  SDP_DiDiscover failed: \
                    Status 0x%2X",status);
#endif
                status = BTA_HH_ERR_SDP;
                utl_freebuf((void **)&bta_hh_cb.p_disc_db);
            }
            else
Пример #5
0
/*******************************************************************************
**
** Function         bta_hh_sdp_cback
**
** Description      SDP callback function.
**
** Returns          void
**
*******************************************************************************/
static void bta_hh_sdp_cback(UINT16 result, UINT16 attr_mask,
                                  tHID_DEV_SDP_INFO *sdp_rec )
{
    tBTA_HH_DEV_CB     *p_cb = bta_hh_cb.p_cur;
    UINT8              hdl = 0;
    tBTA_HH_STATUS    status = BTA_HH_ERR_SDP;

    /* make sure sdp succeeded and hh has not been disabled */
    if ((result == SDP_SUCCESS) && (p_cb != NULL))
    {
        /* security is required for the connection, add attr_mask bit*/
        if (p_cb->sec_mask)
            attr_mask |= HID_SEC_REQUIRED;

#if BTA_HH_DEBUG
        APPL_TRACE_EVENT("bta_hh_sdp_cback: p_cb: %d result 0x%02x, \
                            attr_mask 0x%02x, handle %x", \
                            p_cb, result, attr_mask,p_cb->hid_handle);
#endif

        /* check to see type of device is supported , and should not been added before */
        if (bta_hh_tod_spt(p_cb, sdp_rec->sub_class))
        {
            /* if not added before */
            if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE)
            {
                /*  add device/update attr_mask information */
                if(HID_HostAddDev (p_cb->addr, attr_mask, &hdl) == HID_SUCCESS)
                {
                    status = BTA_HH_OK;
                    /* update cb_index[] map */
                    bta_hh_cb.cb_index[hdl] = p_cb->index;
                }
                else
                {
                    p_cb->app_id = 0;
                }
            }
            else
            {
                hdl = p_cb->hid_handle;
            }
            /* else : incoming connection after SDP should update the SDP information as well */

            if (p_cb->app_id != 0)
            {
                /* update cb information with attr_mask, dscp_info etc. */
                bta_hh_add_device_to_list(p_cb,  hdl, attr_mask,
                                            &sdp_rec->dscp_info,
                                            sdp_rec->sub_class,
                                            sdp_rec->ssr_max_latency,
                                            sdp_rec->ssr_min_tout,
                                            p_cb->app_id);

                p_cb->dscp_info.ctry_code = sdp_rec->ctry_code;

                status = BTA_HH_OK;
            }

        }
        else /* type of device is not supported */
            status = BTA_HH_ERR_TOD_UNSPT;
    }

    /* free disc_db when SDP is completed */
    utl_freebuf((void **)&bta_hh_cb.p_disc_db);

    /* send SDP_CMPL_EVT into state machine */
    bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA *)&status);

    return;
}