*
******************************************************************************/
-/******************************************************************************
- *
- * 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);
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 */
+// 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);
- 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;
+ config_t *config = config_new(p_path);
+ if (!config) {
+ ALOGE("%s unable to load DID config '%s'.", __func__, p_path);
+ return;
+ }
- if (conf_found && (conf_num == num) && (*line == '[')) {
- conf_found = FALSE;
- end_count = count-1;
- break;
- }
+ for (int i = 1; i <= BTA_DI_NUM_MAX; ++i) {
+ char section_name[16] = { 0 };
+ snprintf(section_name, sizeof(section_name), "DID%d", i);
- 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);
- }
+ if (!config_has_section(config, section_name)) {
+ ALOGD("%s no section named %s.", __func__, section_name);
+ break;
}
- 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;
+ 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) {
+ ALOGE("%s invalid vendor id source %d; ignoring DID record %d.", __func__, record.vendor_id_source, i);
+ continue;
}
- 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);
- }
+ 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);
+
+ 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);
}
}
+
+ config_free(config);
}