diff options
-rwxr-xr-x | btif/src/btif_core.c | 6 | ||||
-rw-r--r-- | conf/Android.mk | 8 | ||||
-rwxr-xr-x | conf/bt_did.conf | 94 | ||||
-rw-r--r-- | main/bte_conf.c | 236 |
4 files changed, 344 insertions, 0 deletions
diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c index 47d09f2..b77cddb 100755 --- a/btif/src/btif_core.c +++ b/btif/src/btif_core.c @@ -76,6 +76,10 @@ #define BTIF_TASK_STACK_SIZE 0x2000 /* In bytes */ #endif +#ifndef BTE_DID_CONF_FILE +#define BTE_DID_CONF_FILE "/etc/bluetooth/bt_did.conf" +#endif + #define BTIF_TASK_STR ((INT8 *) "BTIF") static UINT32 btif_task_stack[(BTIF_TASK_STACK_SIZE + 3) / 4]; @@ -119,6 +123,7 @@ static void btif_sendmsg(void *p_msg); /************************************************************************************ ** Externs ************************************************************************************/ +extern void bte_load_did_conf(const char *p_path); /** TODO: Move these to _common.h */ void bte_main_boot_entry(void); @@ -428,6 +433,7 @@ void btif_enable_bluetooth_evt(tBTA_STATUS status, BD_ADDR local_bd) btif_enabled = 1; //init rfcomm & l2cap api btif_sock_init(); + bte_load_did_conf(BTE_DID_CONF_FILE); HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_ON); } else diff --git a/conf/Android.mk b/conf/Android.mk index c590724..63e3c7c 100644 --- a/conf/Android.mk +++ b/conf/Android.mk @@ -11,6 +11,14 @@ LOCAL_MODULE_TAGS := eng LOCAL_SRC_FILES := $(LOCAL_MODULE) +LOCAL_MODULE := bt_did.conf +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/bluetooth + +LOCAL_MODULE_TAGS := eng + +LOCAL_SRC_FILES := bt_did.conf + include $(BUILD_PREBUILT) ifeq ($(TARGET_PRODUCT), full_maguro) diff --git a/conf/bt_did.conf b/conf/bt_did.conf new file mode 100755 index 0000000..2b88d5e --- /dev/null +++ b/conf/bt_did.conf @@ -0,0 +1,94 @@ +# Device ID (DID) configuration
+[DID]
+
+# Record Number: 1, 2 or 3 - maximum of 3 records
+recordNumber = 1
+
+# Primary Record - true or false (default)
+# There can be only one primary record
+primaryRecord = true
+
+# Vendor ID '0xFFFF' indicates no Device ID Service Record is present in the device
+# 0x000F = Broadcom Corporation (default)
+#vendorId = 0x000F
+
+# Vendor ID Source
+# 0x0001 = Bluetooth SIG assigned Device ID Vendor ID value (default)
+# 0x0002 = USB Implementer’s Forum assigned Device ID Vendor ID value
+#vendorIdSource = 0x0001
+
+# Product ID & Product Version
+# Per spec DID v1.3 0xJJMN for version is interpreted as JJ.M.N
+# JJ: major version number, M: minor version number, N: sub-minor version number
+# For example: 1200, v14.3.6
+productId = 0x1200
+version = 0x1436
+
+# Optional attributes
+#clientExecutableURL =
+#serviceDescription =
+#documentationURL =
+
+#=================================================================================================#
+# Device ID (DID) configuration
+[DID]
+
+# Record number: 1, 2 or 3 - maximum of 3 records
+#recordNumber = 2
+
+# Primary Record - true or false (default)
+# There can be only one primary record
+#primaryRecord = false
+
+# Vendor ID '0xFFFF' indicates no Device ID Service Record is present in the device
+# 0x000F = Broadcom Corporation (default)
+#vendorId = 0x000F
+
+# Vendor ID Source
+# 0x0001 = Bluetooth SIG assigned Device ID Vendor ID value (default)
+# 0x0002 = USB Implementer’s Forum assigned Device ID Vendor ID value
+#vendorIdSource = 0x0001
+
+# Product ID & Product Version
+# Per spec DID v1.3 0xJJMN for version is interpreted as JJ.M.N
+# JJ: major version number, M: minor version number, N: sub-minor version number
+# Default: 0x0000, v00.0.0
+#productId = 0x0000
+#version = 0x0000
+
+# Optional attributes
+#clientExecutableURL =
+#serviceDescription =
+#documentationURL =
+
+#=================================================================================================#
+# Device ID (DID) configuration
+[DID]
+
+# Record number: 1, 2 or 3 - maximum of 3 records
+#recordNumber = 3
+
+# Primary Record - true or false (default)
+# There can be only one primary record
+#primaryRecord = false
+
+# Vendor ID '0xFFFF' indicates no Device ID Service Record is present in the device
+# 0x000F = Broadcom Corporation (default)
+#vendorId = 0x000F
+
+# Vendor ID Source
+# 0x0001 = Bluetooth SIG assigned Device ID Vendor ID value (default)
+# 0x0002 = USB Implementer’s Forum assigned Device ID Vendor ID value
+#vendorIdSource = 0x0001
+
+# Product ID & Product Version
+# Per spec DID v1.3 0xJJMN for version is interpreted as JJ.M.N
+# JJ: major version number, M: minor version number, N: sub-minor version number
+# Default: 0x0000, v00.0.0
+#productId = 0x0000
+#version = 0x0000
+
+# Optional attributes
+#clientExecutableURL =
+#serviceDescription =
+#documentationURL =
diff --git a/main/bte_conf.c b/main/bte_conf.c index a24a138..a03e7be 100644 --- a/main/bte_conf.c +++ b/main/bte_conf.c @@ -59,8 +59,11 @@ #include <utils/Log.h> #include <stdio.h> #include <string.h> +#include <stdlib.h> +#include <ctype.h> #include "bt_target.h" +#include "bta_api.h" /****************************************************************************** ** Externs @@ -77,6 +80,13 @@ DEV_CLASS local_device_default_class = {0x40, 0x02, 0x0C}; /****************************************************************************** ** Local type definitions ******************************************************************************/ +#define CONF_DBG 0 +#define info(format, ...) LOGI (format, ## __VA_ARGS__) +#define debug(format, ...) if (CONF_DBG) LOGD (format, ## __VA_ARGS__) +#define error(format, ...) LOGE (format, ## __VA_ARGS__) + +#define CONF_KEY_LEN 32 +#define CONF_VALUE_LEN 96 #define CONF_COMMENT '#' #define CONF_DELIMITERS " =\n\r\t" @@ -91,6 +101,25 @@ typedef struct { 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 ******************************************************************************/ @@ -106,6 +135,18 @@ static const conf_entry_t conf_table[] = { {(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 *****************************************************************************/ @@ -219,3 +260,198 @@ void bte_load_conf(const char *p_path) } } +/******************************************************************************* +** +** 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 */ + + LOGI("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 + { + LOGI( "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; + } + + 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); + } + } + } +} + |