예제 #1
0
/*******************************************************************************
**
** Function         bta_hl_find_sink_or_src_srv_class_in_db
**
** Description      This function queries an SDP database for either a HDP Sink or
**                  Source service class ID.
**                  If the p_start_rec pointer is NULL, it looks from the beginning
**                  of the database, else it continues from the next record after
**                  p_start_rec.
**
** Returns          Pointer to record containing service class, or NULL
**
*******************************************************************************/
tSDP_DISC_REC *bta_hl_find_sink_or_src_srv_class_in_db (const tSDP_DISCOVERY_DB *p_db,
                                                        const tSDP_DISC_REC *p_start_rec)
{
#if SDP_CLIENT_ENABLED == TRUE
    tSDP_DISC_REC   *p_rec;
    tSDP_DISC_ATTR  *p_attr, *p_sattr;

    /* Must have a valid database */
    if (p_db == NULL)
        return(NULL);


    if (!p_start_rec)
    {

        p_rec = p_db->p_first_rec;
    }
    else
    {
        p_rec = p_start_rec->p_next_rec;
    }

    while (p_rec)
    {
        p_attr = p_rec->p_first_attr;
        while (p_attr)
        {
            if ((p_attr->attr_id == ATTR_ID_SERVICE_CLASS_ID_LIST)
                && (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE))
            {
                for (p_sattr = p_attr->attr_value.v.p_sub_attr; p_sattr; p_sattr = p_sattr->p_next_attr)
                {
                    if ((SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == UUID_DESC_TYPE)
                        && (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == 2)
                        && ( (p_sattr->attr_value.v.u16 == UUID_SERVCLASS_HDP_SINK) ||
                             (p_sattr->attr_value.v.u16 == UUID_SERVCLASS_HDP_SOURCE)) )
                    {
                        return(p_rec);
                    }
                }
                break;
            }

            p_attr = p_attr->p_next_attr;
        }

        p_rec = p_rec->p_next_rec;
    }
#endif
    /* If here, no matching UUID found */

#if BTA_HL_DEBUG == TRUE
    APPL_TRACE_DEBUG("bta_hl_find_sink_or_src_srv_class_in_db failed");
#endif

    return(NULL);
}
예제 #2
0
/*******************************************************************************
**
** Function         bta_hl_fill_sup_feature_list
**
** Description      Fill the supported features from teh SDP record
**
** Returns          TRUE if found, FALSE if not
**                  If found, the passed protocol list element is filled in.
**
*******************************************************************************/
BOOLEAN bta_hl_fill_sup_feature_list( const tSDP_DISC_ATTR  *p_attr,
                                      tBTA_HL_SUP_FEATURE_LIST_ELEM *p_list)
{
    tSDP_DISC_ATTR  *p_sattr;
    UINT8           seq_len, item_cnt;
    UINT8           list_cnt=0;
    BOOLEAN         status=TRUE;

    for (p_attr = p_attr->attr_value.v.p_sub_attr; p_attr; p_attr = p_attr->p_next_attr)
    {
        /* mdep sequence */
        if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE)
        {
            return(FALSE);
        }
        seq_len =SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
        item_cnt=0;

        for (p_sattr = p_attr->attr_value.v.p_sub_attr; p_sattr && (item_cnt < 4) ; p_sattr = p_sattr->p_next_attr)
        {
            /* for each mdep list */

            p_list->list_elem[list_cnt].p_mdep_desp = NULL;
            switch (item_cnt)
            {
                case 0:
                    p_list->list_elem[list_cnt].mdep_id = p_sattr->attr_value.v.u8;
                    break;
                case 1:
                    p_list->list_elem[list_cnt].data_type = p_sattr->attr_value.v.u16;
                    break;
                case 2:
                    p_list->list_elem[list_cnt].mdep_role = (tBTA_HL_MDEP_ROLE) p_sattr->attr_value.v.u8;
                    break;
                case 3:
                    p_list->list_elem[list_cnt].p_mdep_desp    = (char *) p_sattr->attr_value.v.array;
                    break;
            }

            item_cnt++;
        }
        list_cnt++;
    }
    p_list->num_elems = list_cnt;
    return(status);
}
예제 #3
0
static void hidh_search_callback (UINT16 sdp_result)
{
    tSDP_DISCOVERY_DB       *p_db = hh_cb.p_sdp_db;
    tSDP_DISC_REC           *p_rec;
    tSDP_DISC_ATTR          *p_attr, *p_subattr1, *p_subattr2, *p_repdesc;
    tBT_UUID                hid_uuid;
    tHID_DEV_SDP_INFO       *p_nvi = &hh_cb.sdp_rec;
    UINT16                  attr_mask = 0;

    hid_uuid.len       = LEN_UUID_16;
    hid_uuid.uu.uuid16 = UUID_SERVCLASS_HUMAN_INTERFACE;

    hh_cb.sdp_busy = FALSE;

    if (sdp_result != SDP_SUCCESS)
    {
        hh_cb.sdp_cback(sdp_result, 0, NULL);
        return;
    }

    if ((p_rec = SDP_FindServiceUUIDInDb (p_db, &hid_uuid, NULL)) == NULL)
    {
        hh_cb.sdp_cback(HID_SDP_NO_SERV_UUID, 0, NULL);
        return;
    }

    memset (&hh_cb.sdp_rec, 0, sizeof( tHID_DEV_SDP_INFO ));

    /* First, verify the mandatory fields we care about */
    if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_DESCRIPTOR_LIST)) == NULL)
     || (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE)
     || ((p_subattr1 = p_attr->attr_value.v.p_sub_attr) == NULL)
     || (SDP_DISC_ATTR_TYPE(p_subattr1->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE)
     || ((p_subattr2 = p_subattr1->attr_value.v.p_sub_attr) == NULL)
     || ((p_repdesc = p_subattr2->p_next_attr) == NULL)
     || (SDP_DISC_ATTR_TYPE(p_repdesc->attr_len_type) != TEXT_STR_DESC_TYPE))
    {
        hh_cb.sdp_cback(HID_SDP_MANDATORY_MISSING, 0, NULL);
        return;
    }

    if ((p_nvi->dscp_info.dl_len = SDP_DISC_ATTR_LEN(p_repdesc->attr_len_type)) != 0)
        p_nvi->dscp_info.dsc_list = (UINT8 *) &p_repdesc->attr_value;

    if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_VIRTUAL_CABLE)) != NULL) &&
        (p_attr->attr_value.v.u8) )
    {
        attr_mask |= HID_VIRTUAL_CABLE;
    }

    if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_RECONNECT_INITIATE)) != NULL) &&
        (p_attr->attr_value.v.u8) )
    {
        attr_mask |= HID_RECONN_INIT;
    }

    if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_NORMALLY_CONNECTABLE)) != NULL) &&
        (p_attr->attr_value.v.u8) )
    {
        attr_mask |= HID_NORMALLY_CONNECTABLE;
    }

    if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_SDP_DISABLE)) != NULL)&&
        (p_attr->attr_value.v.u8) )
    {
        attr_mask |= HID_SDP_DISABLE;
    }

    if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_BATTERY_POWER)) != NULL)&&
        (p_attr->attr_value.v.u8) )
    {
        attr_mask |= HID_BATTERY_POWER;
    }

    if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_REMOTE_WAKE)) != NULL)&&
        (p_attr->attr_value.v.u8) )
    {
        attr_mask |= HID_REMOTE_WAKE;
    }

    hidh_get_str_attr( p_rec, ATTR_ID_SERVICE_NAME, HID_MAX_SVC_NAME_LEN, p_nvi->svc_name );
    hidh_get_str_attr( p_rec, ATTR_ID_SERVICE_DESCRIPTION, HID_MAX_SVC_DESCR_LEN, p_nvi->svc_descr );
    hidh_get_str_attr( p_rec, ATTR_ID_PROVIDER_NAME, HID_MAX_PROV_NAME_LEN, p_nvi->prov_name );

    if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_DEVICE_RELNUM)) != NULL))
    {
        p_nvi->rel_num = p_attr->attr_value.v.u16;
    }

    if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_COUNTRY_CODE)) != NULL))
    {
        p_nvi->ctry_code = p_attr->attr_value.v.u8;
    }

    if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_DEVICE_SUBCLASS)) != NULL))
    {
        p_nvi->sub_class = p_attr->attr_value.v.u8;
    }

    if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_PARSER_VERSION)) != NULL))
    {
        p_nvi->hpars_ver = p_attr->attr_value.v.u16;
    }

    if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_LINK_SUPERVISION_TO)) != NULL))
    {
        attr_mask |= HID_SUP_TOUT_AVLBL;
        p_nvi->sup_timeout = p_attr->attr_value.v.u16;
    }

    if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_SSR_HOST_MAX_LAT)) != NULL))
    {
        attr_mask |= HID_SSR_MAX_LATENCY;
        p_nvi->ssr_max_latency = p_attr->attr_value.v.u16;
    }
    else
        p_nvi->ssr_max_latency = HID_SSR_PARAM_INVALID;

    if (((p_attr = SDP_FindAttributeInRec (p_rec, ATTR_ID_HID_SSR_HOST_MIN_TOUT)) != NULL))
    {
        attr_mask |= HID_SSR_MIN_TOUT;
        p_nvi->ssr_min_tout = p_attr->attr_value.v.u16;
    }
    else
        p_nvi->ssr_max_latency = HID_SSR_PARAM_INVALID;

    hh_cb.sdp_rec.p_sdp_layer_rec = p_rec;
    hh_cb.sdp_cback(SDP_SUCCESS, attr_mask, &hh_cb.sdp_rec);
}