Loading system/conf/bt_did.conf +3 −12 Original line number Diff line number Diff line # Device ID (DID) configuration [DID] # Record Number: 1, 2 or 3 - maximum of 3 records recordNumber = 1 [DID1] # Primary Record - true or false (default) # There can be only one primary record Loading Loading @@ -31,10 +28,7 @@ version = 0x1436 #=================================================================================================# # Device ID (DID) configuration [DID] # Record number: 1, 2 or 3 - maximum of 3 records #recordNumber = 2 [DID2] # Primary Record - true or false (default) # There can be only one primary record Loading Loading @@ -63,10 +57,7 @@ version = 0x1436 #=================================================================================================# # Device ID (DID) configuration [DID] # Record number: 1, 2 or 3 - maximum of 3 records #recordNumber = 3 [DID3] # Primary Record - true or false (default) # There can be only one primary record Loading system/main/bte_conf.c +52 −359 Original line number Diff line number Diff line Loading @@ -16,189 +16,24 @@ * ******************************************************************************/ /****************************************************************************** * * Filename: bte_conf.c * * Description: Contains functions to conduct run-time module configuration * based on entries present in the .conf file * ******************************************************************************/ #define LOG_TAG "bte_conf" #include <assert.h> #include <utils/Log.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <utils/Log.h> #include "bt_target.h" #include "bta_api.h" #include "bt_utils.h" #include "config.h" /****************************************************************************** ** Externs ******************************************************************************/ extern BOOLEAN hci_logging_enabled; // TODO: eliminate these global variables. extern char hci_logfile[256]; extern BOOLEAN hci_logging_enabled; extern BOOLEAN trace_conf_enabled; void bte_trace_conf(const char *p_name, const char *p_conf_value); void bte_trace_conf_config(const config_t *config); int device_name_cfg(const char *p_conf_name, const char *p_conf_value); int device_class_cfg(const char *p_conf_name, const char *p_conf_value); int logging_cfg_onoff(const char *p_conf_name, const char *p_conf_value); int logging_set_filepath(const char *p_conf_name, const char *p_conf_value); int trace_cfg_onoff(const char *p_conf_name, const char *p_conf_value); BD_NAME local_device_default_name = BTM_DEF_LOCAL_NAME; DEV_CLASS local_device_default_class = {0x40, 0x02, 0x0C}; /****************************************************************************** ** Local type definitions ******************************************************************************/ #define CONF_DBG 0 #define info(format, ...) ALOGI (format, ## __VA_ARGS__) #define debug(format, ...) if (CONF_DBG) ALOGD (format, ## __VA_ARGS__) #define error(format, ...) ALOGE (format, ## __VA_ARGS__) #define CONF_KEY_LEN 32 #define CONF_VALUE_LEN 96 #define CONF_COMMENT '#' #define CONF_DELIMITERS " =\n\r\t" #define CONF_VALUES_DELIMITERS "\"=\n\r\t" #define CONF_COD_DELIMITERS " {,}\t" #define CONF_MAX_LINE_LEN 255 typedef int (conf_action_t)(const char *p_conf_name, const char *p_conf_value); typedef struct { const char *key_name; conf_action_t *p_action; } conf_entry_t; typedef struct { char key[CONF_KEY_LEN]; char value[CONF_VALUE_LEN]; } tKEY_VALUE_PAIRS; enum { CONF_DID, CONF_DID_RECORD_NUM, CONF_DID_PRIMARY_RECORD, CONF_DID_VENDOR_ID, CONF_DID_VENDOR_ID_SOURCE, CONF_DID_PRODUCT_ID, CONF_DID_VERSION, CONF_DID_CLIENT_EXECUTABLE_URL, CONF_DID_SERVICE_DESCRIPTION, CONF_DID_DOCUMENTATION_URL, CONF_DID_MAX }; typedef UINT8 tCONF_DID; /****************************************************************************** ** Static variables ******************************************************************************/ /* * Current supported entries and corresponding action functions */ /* TODO: Name and Class are duplicated with NVRAM adapter_info. Need to be sorted out */ static const conf_entry_t conf_table[] = { /*{"Name", device_name_cfg}, {"Class", device_class_cfg},*/ {"BtSnoopLogOutput", logging_cfg_onoff}, {"BtSnoopFileName", logging_set_filepath}, {"TraceConf", trace_cfg_onoff}, {(const char *) NULL, NULL} }; static tKEY_VALUE_PAIRS did_conf_pairs[CONF_DID_MAX] = { { "[DID]", "" }, { "recordNumber", "" }, { "primaryRecord", "" }, { "vendorId", "" }, { "vendorIdSource", "" }, { "productId", "" }, { "version", "" }, { "clientExecutableURL", "" }, { "serviceDescription", "" }, { "documentationURL", "" }, }; /***************************************************************************** ** FUNCTIONS *****************************************************************************/ int device_name_cfg(const char *p_conf_name, const char *p_conf_value) { UNUSED(p_conf_name); strcpy((char *)local_device_default_name, p_conf_value); return 0; } int device_class_cfg(const char *p_conf_name, const char *p_conf_value) { char *p_token; unsigned int x; char tmp[1024] = { 0 }; strncpy(tmp, p_conf_value, sizeof(tmp) - 1); UNUSED(p_conf_name); p_token = strtok(tmp, CONF_COD_DELIMITERS); sscanf(p_token, "%x", &x); local_device_default_class[0] = (UINT8) x; p_token = strtok(NULL, CONF_COD_DELIMITERS); sscanf(p_token, "%x", &x); local_device_default_class[1] = (UINT8) x; p_token = strtok(NULL, CONF_COD_DELIMITERS); sscanf(p_token, "%x", &x); local_device_default_class[2] = (UINT8) x; return 0; } int logging_cfg_onoff(const char *p_conf_name, const char *p_conf_value) { UNUSED(p_conf_name); if (strcmp(p_conf_value, "true") == 0) hci_logging_enabled = TRUE; else hci_logging_enabled = FALSE; return 0; } int logging_set_filepath(const char *p_conf_name, const char *p_conf_value) { UNUSED(p_conf_name); strcpy(hci_logfile, p_conf_value); return 0; } int trace_cfg_onoff(const char *p_conf_name, const char *p_conf_value) { UNUSED(p_conf_name); trace_conf_enabled = (strcmp(p_conf_value, "true") == 0) ? TRUE : FALSE; return 0; } /***************************************************************************** ** CONF INTERFACE FUNCTIONS *****************************************************************************/ /******************************************************************************* ** ** Function bte_load_conf ** ** Description Read conf entry from path file one by one and call ** the corresponding config function ** ** Returns None ** *******************************************************************************/ // Reads the stack configuration file and populates global variables with // the contents of the file. void bte_load_conf(const char *path) { assert(path != NULL); Loading @@ -210,207 +45,65 @@ void bte_load_conf(const char *path) { return; } for (const conf_entry_t *entry = &conf_table[0]; entry->key_name; ++entry) { const char *value = config_get_string(config, CONFIG_DEFAULT_SECTION, entry->key_name, NULL); if (value) entry->p_action(entry->key_name, value); } strlcpy(hci_logfile, config_get_string(config, CONFIG_DEFAULT_SECTION, "BtSnoopFileName", ""), sizeof(hci_logfile)); hci_logging_enabled = config_get_bool(config, CONFIG_DEFAULT_SECTION, "BtSnoopLogOutput", false); trace_conf_enabled = config_get_bool(config, CONFIG_DEFAULT_SECTION, "TraceConf", false); bte_trace_conf_config(config); config_free(config); } /******************************************************************************* ** ** Function bte_parse_did_conf ** ** Description Read conf entry from p_path file one by one and get ** the corresponding config value ** ** Returns TRUE if success, else FALSE ** *******************************************************************************/ static BOOLEAN bte_parse_did_conf (const char *p_path, UINT32 num, tKEY_VALUE_PAIRS *conf_pairs, UINT32 conf_pairs_num) { UINT32 i, param_num=0, count=0, start_count=0, end_count=0, conf_num=0; BOOLEAN key=TRUE, conf_found=FALSE; FILE *p_file; char *p; char line[CONF_MAX_LINE_LEN+1]; /* add 1 for \0 char */ ALOGI("Attempt to load did conf from %s", p_path); if ((p_file = fopen(p_path, "r")) != NULL) { /* read line by line */ while (fgets(line, CONF_MAX_LINE_LEN+1, p_file) != NULL) { count++; if (line[0] == CONF_COMMENT) continue; if (conf_found && (conf_num == num) && (*line == '[')) { conf_found = FALSE; end_count = count-1; break; } p = strtok(line, CONF_DELIMITERS); while (p != NULL) { if (conf_num <= num) { if (key) { if (!strcmp(p, conf_pairs[0].key)) { if (++conf_num == num) { conf_found = TRUE; start_count = count; strncpy(conf_pairs[0].value, "1", CONF_VALUE_LEN); } } else { if (conf_num == num) { for (i=1; i<conf_pairs_num; i++) { if (!strcmp(p, conf_pairs[i].key)) { param_num = i; break; } } if (i == conf_pairs_num) { error("Attribute %s does not belong to %s configuration", p, conf_pairs[0].key); fclose(p_file); return FALSE; } } key = FALSE; } } else { if ((conf_num == num) && param_num) { strncpy(conf_pairs[param_num].value, p, CONF_VALUE_LEN-1); param_num = 0; } key = TRUE; } } p = strtok(NULL, CONF_DELIMITERS); } } fclose(p_file); } else { ALOGI( "bte_parse_did_conf file >%s< not found", p_path); } if (!end_count) end_count = count; if (start_count) { debug("Read %s configuration #%u from lines %u to %u in file %s", conf_pairs[0].key, (unsigned int)num, (unsigned int)start_count, (unsigned int)end_count, p_path); return TRUE; } error("%s configuration not found in file %s", conf_pairs[0].key, p_path); return FALSE; } /******************************************************************************* ** ** Function bte_load_did_conf ** ** Description Set local Device ID records, reading from configuration files ** ** Returns None ** *******************************************************************************/ 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; } // 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); 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; config_t *config = config_new(p_path); if (!config) { ALOGE("%s unable to load DID config '%s'.", __func__, p_path); return; } 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; } 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 (*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 (!config_has_section(config, section_name)) { ALOGD("%s no section named %s.", __func__, section_name); break; } 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)) { 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)); 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); } if (record.vendor_id_source != DI_VENDOR_ID_SOURCE_BTSIG && record.vendor_id_source != DI_VENDOR_ID_SOURCE_USBIF) { ALOGE("%s invalid vendor id source %d; ignoring DID record %d.", __func__, record.vendor_id_source, i); 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); ALOGD("Device ID record %d : %s", i, (record.primary_record ? "primary" : "not primary")); ALOGD(" vendorId = %04x", record.vendor); ALOGD(" vendorIdSource = %04x", record.vendor_id_source); ALOGD(" product = %04x", record.product); ALOGD(" version = %04x", record.version); ALOGD(" clientExecutableURL = %s", record.client_executable_url); ALOGD(" serviceDescription = %s", record.service_description); ALOGD(" documentationURL = %s", record.documentation_url); 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]); uint32_t record_handle; tBTA_STATUS status = BTA_DmSetLocalDiRecord(&record, &record_handle); if (status != BTA_SUCCESS) { ALOGE("%s unable to set device ID record %d: error %d.", __func__, i, status); } 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); } } } config_free(config); } Loading
system/conf/bt_did.conf +3 −12 Original line number Diff line number Diff line # Device ID (DID) configuration [DID] # Record Number: 1, 2 or 3 - maximum of 3 records recordNumber = 1 [DID1] # Primary Record - true or false (default) # There can be only one primary record Loading Loading @@ -31,10 +28,7 @@ version = 0x1436 #=================================================================================================# # Device ID (DID) configuration [DID] # Record number: 1, 2 or 3 - maximum of 3 records #recordNumber = 2 [DID2] # Primary Record - true or false (default) # There can be only one primary record Loading Loading @@ -63,10 +57,7 @@ version = 0x1436 #=================================================================================================# # Device ID (DID) configuration [DID] # Record number: 1, 2 or 3 - maximum of 3 records #recordNumber = 3 [DID3] # Primary Record - true or false (default) # There can be only one primary record Loading
system/main/bte_conf.c +52 −359 Original line number Diff line number Diff line Loading @@ -16,189 +16,24 @@ * ******************************************************************************/ /****************************************************************************** * * Filename: bte_conf.c * * Description: Contains functions to conduct run-time module configuration * based on entries present in the .conf file * ******************************************************************************/ #define LOG_TAG "bte_conf" #include <assert.h> #include <utils/Log.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <utils/Log.h> #include "bt_target.h" #include "bta_api.h" #include "bt_utils.h" #include "config.h" /****************************************************************************** ** Externs ******************************************************************************/ extern BOOLEAN hci_logging_enabled; // TODO: eliminate these global variables. extern char hci_logfile[256]; extern BOOLEAN hci_logging_enabled; extern BOOLEAN trace_conf_enabled; void bte_trace_conf(const char *p_name, const char *p_conf_value); void bte_trace_conf_config(const config_t *config); int device_name_cfg(const char *p_conf_name, const char *p_conf_value); int device_class_cfg(const char *p_conf_name, const char *p_conf_value); int logging_cfg_onoff(const char *p_conf_name, const char *p_conf_value); int logging_set_filepath(const char *p_conf_name, const char *p_conf_value); int trace_cfg_onoff(const char *p_conf_name, const char *p_conf_value); BD_NAME local_device_default_name = BTM_DEF_LOCAL_NAME; DEV_CLASS local_device_default_class = {0x40, 0x02, 0x0C}; /****************************************************************************** ** Local type definitions ******************************************************************************/ #define CONF_DBG 0 #define info(format, ...) ALOGI (format, ## __VA_ARGS__) #define debug(format, ...) if (CONF_DBG) ALOGD (format, ## __VA_ARGS__) #define error(format, ...) ALOGE (format, ## __VA_ARGS__) #define CONF_KEY_LEN 32 #define CONF_VALUE_LEN 96 #define CONF_COMMENT '#' #define CONF_DELIMITERS " =\n\r\t" #define CONF_VALUES_DELIMITERS "\"=\n\r\t" #define CONF_COD_DELIMITERS " {,}\t" #define CONF_MAX_LINE_LEN 255 typedef int (conf_action_t)(const char *p_conf_name, const char *p_conf_value); typedef struct { const char *key_name; conf_action_t *p_action; } conf_entry_t; typedef struct { char key[CONF_KEY_LEN]; char value[CONF_VALUE_LEN]; } tKEY_VALUE_PAIRS; enum { CONF_DID, CONF_DID_RECORD_NUM, CONF_DID_PRIMARY_RECORD, CONF_DID_VENDOR_ID, CONF_DID_VENDOR_ID_SOURCE, CONF_DID_PRODUCT_ID, CONF_DID_VERSION, CONF_DID_CLIENT_EXECUTABLE_URL, CONF_DID_SERVICE_DESCRIPTION, CONF_DID_DOCUMENTATION_URL, CONF_DID_MAX }; typedef UINT8 tCONF_DID; /****************************************************************************** ** Static variables ******************************************************************************/ /* * Current supported entries and corresponding action functions */ /* TODO: Name and Class are duplicated with NVRAM adapter_info. Need to be sorted out */ static const conf_entry_t conf_table[] = { /*{"Name", device_name_cfg}, {"Class", device_class_cfg},*/ {"BtSnoopLogOutput", logging_cfg_onoff}, {"BtSnoopFileName", logging_set_filepath}, {"TraceConf", trace_cfg_onoff}, {(const char *) NULL, NULL} }; static tKEY_VALUE_PAIRS did_conf_pairs[CONF_DID_MAX] = { { "[DID]", "" }, { "recordNumber", "" }, { "primaryRecord", "" }, { "vendorId", "" }, { "vendorIdSource", "" }, { "productId", "" }, { "version", "" }, { "clientExecutableURL", "" }, { "serviceDescription", "" }, { "documentationURL", "" }, }; /***************************************************************************** ** FUNCTIONS *****************************************************************************/ int device_name_cfg(const char *p_conf_name, const char *p_conf_value) { UNUSED(p_conf_name); strcpy((char *)local_device_default_name, p_conf_value); return 0; } int device_class_cfg(const char *p_conf_name, const char *p_conf_value) { char *p_token; unsigned int x; char tmp[1024] = { 0 }; strncpy(tmp, p_conf_value, sizeof(tmp) - 1); UNUSED(p_conf_name); p_token = strtok(tmp, CONF_COD_DELIMITERS); sscanf(p_token, "%x", &x); local_device_default_class[0] = (UINT8) x; p_token = strtok(NULL, CONF_COD_DELIMITERS); sscanf(p_token, "%x", &x); local_device_default_class[1] = (UINT8) x; p_token = strtok(NULL, CONF_COD_DELIMITERS); sscanf(p_token, "%x", &x); local_device_default_class[2] = (UINT8) x; return 0; } int logging_cfg_onoff(const char *p_conf_name, const char *p_conf_value) { UNUSED(p_conf_name); if (strcmp(p_conf_value, "true") == 0) hci_logging_enabled = TRUE; else hci_logging_enabled = FALSE; return 0; } int logging_set_filepath(const char *p_conf_name, const char *p_conf_value) { UNUSED(p_conf_name); strcpy(hci_logfile, p_conf_value); return 0; } int trace_cfg_onoff(const char *p_conf_name, const char *p_conf_value) { UNUSED(p_conf_name); trace_conf_enabled = (strcmp(p_conf_value, "true") == 0) ? TRUE : FALSE; return 0; } /***************************************************************************** ** CONF INTERFACE FUNCTIONS *****************************************************************************/ /******************************************************************************* ** ** Function bte_load_conf ** ** Description Read conf entry from path file one by one and call ** the corresponding config function ** ** Returns None ** *******************************************************************************/ // Reads the stack configuration file and populates global variables with // the contents of the file. void bte_load_conf(const char *path) { assert(path != NULL); Loading @@ -210,207 +45,65 @@ void bte_load_conf(const char *path) { return; } for (const conf_entry_t *entry = &conf_table[0]; entry->key_name; ++entry) { const char *value = config_get_string(config, CONFIG_DEFAULT_SECTION, entry->key_name, NULL); if (value) entry->p_action(entry->key_name, value); } strlcpy(hci_logfile, config_get_string(config, CONFIG_DEFAULT_SECTION, "BtSnoopFileName", ""), sizeof(hci_logfile)); hci_logging_enabled = config_get_bool(config, CONFIG_DEFAULT_SECTION, "BtSnoopLogOutput", false); trace_conf_enabled = config_get_bool(config, CONFIG_DEFAULT_SECTION, "TraceConf", false); bte_trace_conf_config(config); config_free(config); } /******************************************************************************* ** ** Function bte_parse_did_conf ** ** Description Read conf entry from p_path file one by one and get ** the corresponding config value ** ** Returns TRUE if success, else FALSE ** *******************************************************************************/ static BOOLEAN bte_parse_did_conf (const char *p_path, UINT32 num, tKEY_VALUE_PAIRS *conf_pairs, UINT32 conf_pairs_num) { UINT32 i, param_num=0, count=0, start_count=0, end_count=0, conf_num=0; BOOLEAN key=TRUE, conf_found=FALSE; FILE *p_file; char *p; char line[CONF_MAX_LINE_LEN+1]; /* add 1 for \0 char */ ALOGI("Attempt to load did conf from %s", p_path); if ((p_file = fopen(p_path, "r")) != NULL) { /* read line by line */ while (fgets(line, CONF_MAX_LINE_LEN+1, p_file) != NULL) { count++; if (line[0] == CONF_COMMENT) continue; if (conf_found && (conf_num == num) && (*line == '[')) { conf_found = FALSE; end_count = count-1; break; } p = strtok(line, CONF_DELIMITERS); while (p != NULL) { if (conf_num <= num) { if (key) { if (!strcmp(p, conf_pairs[0].key)) { if (++conf_num == num) { conf_found = TRUE; start_count = count; strncpy(conf_pairs[0].value, "1", CONF_VALUE_LEN); } } else { if (conf_num == num) { for (i=1; i<conf_pairs_num; i++) { if (!strcmp(p, conf_pairs[i].key)) { param_num = i; break; } } if (i == conf_pairs_num) { error("Attribute %s does not belong to %s configuration", p, conf_pairs[0].key); fclose(p_file); return FALSE; } } key = FALSE; } } else { if ((conf_num == num) && param_num) { strncpy(conf_pairs[param_num].value, p, CONF_VALUE_LEN-1); param_num = 0; } key = TRUE; } } p = strtok(NULL, CONF_DELIMITERS); } } fclose(p_file); } else { ALOGI( "bte_parse_did_conf file >%s< not found", p_path); } if (!end_count) end_count = count; if (start_count) { debug("Read %s configuration #%u from lines %u to %u in file %s", conf_pairs[0].key, (unsigned int)num, (unsigned int)start_count, (unsigned int)end_count, p_path); return TRUE; } error("%s configuration not found in file %s", conf_pairs[0].key, p_path); return FALSE; } /******************************************************************************* ** ** Function bte_load_did_conf ** ** Description Set local Device ID records, reading from configuration files ** ** Returns None ** *******************************************************************************/ 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; } // 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); 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; config_t *config = config_new(p_path); if (!config) { ALOGE("%s unable to load DID config '%s'.", __func__, p_path); return; } 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; } 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 (*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 (!config_has_section(config, section_name)) { ALOGD("%s no section named %s.", __func__, section_name); break; } 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)) { 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)); 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); } if (record.vendor_id_source != DI_VENDOR_ID_SOURCE_BTSIG && record.vendor_id_source != DI_VENDOR_ID_SOURCE_USBIF) { ALOGE("%s invalid vendor id source %d; ignoring DID record %d.", __func__, record.vendor_id_source, i); 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); ALOGD("Device ID record %d : %s", i, (record.primary_record ? "primary" : "not primary")); ALOGD(" vendorId = %04x", record.vendor); ALOGD(" vendorIdSource = %04x", record.vendor_id_source); ALOGD(" product = %04x", record.product); ALOGD(" version = %04x", record.version); ALOGD(" clientExecutableURL = %s", record.client_executable_url); ALOGD(" serviceDescription = %s", record.service_description); ALOGD(" documentationURL = %s", record.documentation_url); 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]); uint32_t record_handle; tBTA_STATUS status = BTA_DmSetLocalDiRecord(&record, &record_handle); if (status != BTA_SUCCESS) { ALOGE("%s unable to set device ID record %d: error %d.", __func__, i, status); } 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); } } } config_free(config); }