/******************************************************************************* ** ** 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); }
/******************************************************************************* ** ** 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); }
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); }