// Parses the specified Device ID configuration file and registers the // Device ID records with SDP. void bte_load_did_conf(const char *p_path) { assert(p_path != NULL); config_t *config = config_new(p_path); if (!config) { LOG_ERROR(LOG_TAG, "%s unable to load DID config '%s'.", __func__, p_path); return; } for (int i = 1; i <= BTA_DI_NUM_MAX; ++i) { char section_name[16] = { 0 }; snprintf(section_name, sizeof(section_name), "DID%d", i); if (!config_has_section(config, section_name)) { LOG_DEBUG(LOG_TAG, "%s no section named %s.", __func__, section_name); break; } tBTA_DI_RECORD record; record.vendor = config_get_int(config, section_name, "vendorId", LMP_COMPID_BROADCOM); record.vendor_id_source = config_get_int(config, section_name, "vendorIdSource", DI_VENDOR_ID_SOURCE_BTSIG); record.product = config_get_int(config, section_name, "productId", 0); record.version = config_get_int(config, section_name, "version", 0); record.primary_record = config_get_bool(config, section_name, "primaryRecord", false); strlcpy(record.client_executable_url, config_get_string(config, section_name, "clientExecutableURL", ""), sizeof(record.client_executable_url)); strlcpy(record.service_description, config_get_string(config, section_name, "serviceDescription", ""), sizeof(record.service_description)); strlcpy(record.documentation_url, config_get_string(config, section_name, "documentationURL", ""), sizeof(record.documentation_url)); if (record.vendor_id_source != DI_VENDOR_ID_SOURCE_BTSIG && record.vendor_id_source != DI_VENDOR_ID_SOURCE_USBIF) { LOG_ERROR(LOG_TAG, "%s invalid vendor id source %d; ignoring DID record %d.", __func__, record.vendor_id_source, i); continue; } LOG_DEBUG(LOG_TAG, "Device ID record %d : %s", i, (record.primary_record ? "primary" : "not primary")); LOG_DEBUG(LOG_TAG, " vendorId = %04x", record.vendor); LOG_DEBUG(LOG_TAG, " vendorIdSource = %04x", record.vendor_id_source); LOG_DEBUG(LOG_TAG, " product = %04x", record.product); LOG_DEBUG(LOG_TAG, " version = %04x", record.version); LOG_DEBUG(LOG_TAG, " clientExecutableURL = %s", record.client_executable_url); LOG_DEBUG(LOG_TAG, " serviceDescription = %s", record.service_description); LOG_DEBUG(LOG_TAG, " documentationURL = %s", record.documentation_url); uint32_t record_handle; tBTA_STATUS status = BTA_DmSetLocalDiRecord(&record, &record_handle); if (status != BTA_SUCCESS) { LOG_ERROR(LOG_TAG, "%s unable to set device ID record %d: error %d.", __func__, i, status); } } config_free(config); }
void bte_load_did_conf (const char *p_path) { tBTA_DI_RECORD rec; UINT32 rec_num, i, j; for (i=1; i<=BTA_DI_NUM_MAX; i++) { for (j=0; j<CONF_DID_MAX; j++) { *did_conf_pairs[j].value = 0; } if (bte_parse_did_conf(p_path, i, did_conf_pairs, CONF_DID_MAX)) { memset(&rec, 0, sizeof(rec)); if (*did_conf_pairs[CONF_DID_RECORD_NUM].value) { rec_num = (UINT32)(strtoul(did_conf_pairs[CONF_DID_RECORD_NUM].value, NULL, 0)-1); } else { debug("[%d] Unknown %s", (unsigned int)i, did_conf_pairs[CONF_DID_RECORD_NUM].key); continue; } if (*did_conf_pairs[CONF_DID_VENDOR_ID].value) { rec.vendor = (UINT16)strtoul(did_conf_pairs[CONF_DID_VENDOR_ID].value, NULL, 0); } else { rec.vendor = LMP_COMPID_BROADCOM; } if (*did_conf_pairs[CONF_DID_VENDOR_ID_SOURCE].value) { rec.vendor_id_source = (UINT16)strtoul(did_conf_pairs[CONF_DID_VENDOR_ID_SOURCE].value, NULL, 0); } else { rec.vendor_id_source = DI_VENDOR_ID_SOURCE_BTSIG; } if ((*did_conf_pairs[CONF_DID].value == 0) || (rec_num >= BTA_DI_NUM_MAX) || (!((rec.vendor_id_source >= DI_VENDOR_ID_SOURCE_BTSIG) && (rec.vendor_id_source <= DI_VENDOR_ID_SOURCE_USBIF))) || (rec.vendor == DI_VENDOR_ID_DEFAULT)) { error("DID record #%u not set", (unsigned int)i); for (j=0; j<CONF_DID_MAX; j++) { error("%s:%s", did_conf_pairs[j].key, did_conf_pairs[j].value); } continue; } rec.product = (UINT16)strtoul(did_conf_pairs[CONF_DID_PRODUCT_ID].value, NULL, 0); rec.version = (UINT16)strtoul(did_conf_pairs[CONF_DID_VERSION].value, NULL, 0); strncpy(rec.client_executable_url, did_conf_pairs[CONF_DID_CLIENT_EXECUTABLE_URL].value, SDP_MAX_ATTR_LEN); strncpy(rec.service_description, did_conf_pairs[CONF_DID_SERVICE_DESCRIPTION].value, SDP_MAX_ATTR_LEN); strncpy(rec.documentation_url, did_conf_pairs[CONF_DID_DOCUMENTATION_URL].value, SDP_MAX_ATTR_LEN); for (j=0; j<strlen(did_conf_pairs[CONF_DID_PRIMARY_RECORD].value); j++) { did_conf_pairs[CONF_DID_PRIMARY_RECORD].value[j] = tolower(did_conf_pairs[CONF_DID_PRIMARY_RECORD].value[j]); } if ((!strcmp(did_conf_pairs[CONF_DID_PRIMARY_RECORD].value, "true")) || (!strcmp(did_conf_pairs[CONF_DID_PRIMARY_RECORD].value, "1"))) { rec.primary_record = TRUE; } else { rec.primary_record = FALSE; } info("[%u] primary_record=%d vendor_id=0x%04X vendor_id_source=0x%04X product_id=0x%04X version=0x%04X", (unsigned int)rec_num+1, rec.primary_record, rec.vendor, rec.vendor_id_source, rec.product, rec.version); if (*rec.client_executable_url) { info(" client_executable_url=%s", rec.client_executable_url); } if (*rec.service_description) { info(" service_description=%s", rec.service_description); } if (*rec.documentation_url) { info(" documentation_url=%s", rec.documentation_url); } if (BTA_DmSetLocalDiRecord(&rec, &rec_num) != BTA_SUCCESS) { error("SetLocalDiInfo failed for #%u!", (unsigned int)i); } } } }