summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--btif/include/btif_config.h95
-rw-r--r--btif/include/btif_config_util.h80
-rw-r--r--btif/include/btif_sock_thread.h4
-rw-r--r--btif/include/btif_util.h1
-rw-r--r--btif/src/btif_config.c843
-rw-r--r--btif/src/btif_config_util.cpp702
-rwxr-xr-xbtif/src/btif_core.c18
-rwxr-xr-xbtif/src/btif_dm.c4
-rw-r--r--btif/src/btif_pan.c2
-rw-r--r--btif/src/btif_sock.c2
-rw-r--r--btif/src/btif_sock_thread.c79
-rwxr-xr-xbtif/src/btif_storage.c1154
-rw-r--r--btif/src/btif_util.c6
-rwxr-xr-xmain/Android.mk5
14 files changed, 2147 insertions, 848 deletions
diff --git a/btif/include/btif_config.h b/btif/include/btif_config.h
new file mode 100644
index 0000000..7188a0f
--- /dev/null
+++ b/btif/include/btif_config.h
@@ -0,0 +1,95 @@
+/************************************************************************************
+ *
+ * Copyright (C) 2009-2011 Broadcom Corporation
+ *
+ * This program is the proprietary software of Broadcom Corporation and/or its
+ * licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and Broadcom (an "Authorized License").
+ * Except as set forth in an Authorized License, Broadcom grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and Broadcom expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein.
+ * IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS
+ * SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+ * ALL USE OF THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of Broadcom, and you shall
+ * use all reasonable efforts to protect the confidentiality thereof,
+ * and to use this information only in connection with your use of
+ * Broadcom integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+ * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
+ * OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+ * ITS LICENSORS BE LIABLE FOR
+ * (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY
+ * DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO
+ * YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM
+ * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR
+ * (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+ * SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
+ * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF
+ * ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ ************************************************************************************/
+
+
+/************************************************************************************
+ *
+ * Filename: btif_config.h
+ *
+ * Description: Bluetooth configuration Interface
+ *
+ *
+ ***********************************************************************************/
+
+#ifndef btif_config_h_
+#define btif_config_h_
+#ifdef __cplusplus
+#include <stdint.h>
+extern "C" {
+#endif
+#define BTIF_CFG_TYPE_INVALID 0
+#define BTIF_CFG_TYPE_STR 1
+#define BTIF_CFG_TYPE_INT (1 << 1)
+#define BTIF_CFG_TYPE_BIN (1 << 2)
+#define BTIF_CFG_TYPE_VOLATILE (1 << 15)
+int btif_config_init();
+
+int btif_config_exist(const char* section, const char* key, const char* name);
+int btif_config_get_int(const char* section, const char* key, const char* name, int* value);
+int btif_config_set_int(const char* section, const char* key, const char* name, int value);
+int btif_config_get_str(const char* section, const char* key, const char* name, char* value, int* bytes);
+int btif_config_set_str(const char* section, const char* key, const char* name, const char* value);
+
+int btif_config_get(const char* section, const char* key, const char* name, char* value, int* bytes, int* type);
+int btif_config_set(const char* section, const char* key, const char* name, const char* value, int bytes, int type);
+
+int btif_config_remove(const char* section, const char* key, const char* name);
+
+short btif_config_next_key(short current_key_pos, const char* section, char * key_name, int* key_name_bytes);
+short btif_config_next_value(short pos, const char* section, const char* key, char* value_name, int* value_name_bytes);
+
+typedef void (*btif_config_enum_callback)(void* user_data, const char* section, const char* key, const char* name,
+ const char* value, int bytes, int type);
+int btif_config_enum(btif_config_enum_callback cb, void* user_data);
+
+int btif_config_save();
+void btif_config_flush();
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/btif/include/btif_config_util.h b/btif/include/btif_config_util.h
new file mode 100644
index 0000000..0612796
--- /dev/null
+++ b/btif/include/btif_config_util.h
@@ -0,0 +1,80 @@
+/************************************************************************************
+ *
+ * Copyright (C) 2009-2011 Broadcom Corporation
+ *
+ * This program is the proprietary software of Broadcom Corporation and/or its
+ * licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and Broadcom (an "Authorized License").
+ * Except as set forth in an Authorized License, Broadcom grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and Broadcom expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein.
+ * IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS
+ * SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+ * ALL USE OF THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of Broadcom, and you shall
+ * use all reasonable efforts to protect the confidentiality thereof,
+ * and to use this information only in connection with your use of
+ * Broadcom integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+ * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
+ * OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+ * ITS LICENSORS BE LIABLE FOR
+ * (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY
+ * DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO
+ * YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM
+ * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR
+ * (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+ * SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
+ * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF
+ * ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ ************************************************************************************/
+
+
+/************************************************************************************
+ *
+ * Filename: btif_config_util.h
+ *
+ * Description: Bluetooth configuration utility api
+ *
+ *
+ ***********************************************************************************/
+
+#ifndef btif_config_util_h_
+#define btif_config_util_h_
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define BLUEZ_PATH "/data/misc/bluetoothd/"
+#define BLUEZ_PATH_BAK "/data/misc/bluetoothd_bak"
+#define BLUEZ_LINKKEY "linkkeys"
+#define BLUEZ_NAMES "names"
+#define BLUEZ_PROFILES "profiles"
+#define BLUEZ_CLASSES "classes"
+#define BLUEZ_TYPES "types"
+#define BLUEZ_CONFIG "config"
+#define BLUEZ_ALIASES "aliases"
+int btif_config_save_file(const char* file_name);
+int btif_config_load_file(const char* file_name);
+int load_bluez_adapter_info(char* adapter_path, int size);
+int load_bluez_linkkeys(const char* adapter_path);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/btif/include/btif_sock_thread.h b/btif/include/btif_sock_thread.h
index 1e2fe0c..0f5212f 100644
--- a/btif/include/btif_sock_thread.h
+++ b/btif/include/btif_sock_thread.h
@@ -64,8 +64,10 @@
int btsock_thread_init();
int btsock_thread_add_fd(int handle, int fd, int type, int flags, uint32_t user_id);
int btsock_thread_wakeup(int handle);
+int btsock_thread_post_cmd(int handle, int cmd_type, const unsigned char* cmd_data, int data_size, uint32_t user_id);
typedef void (*btsock_signaled_cb)(int fd, int type, int flags, uint32_t user_id);
-int btsock_thread_create(btsock_signaled_cb callback);
+typedef void (*btsock_cmd_cb)(int cmd_fd, int type, int size, uint32_t user_id);
+int btsock_thread_create(btsock_signaled_cb callback, btsock_cmd_cb cmd_callback);
int btsock_thread_exit(int handle);
#endif
diff --git a/btif/include/btif_util.h b/btif/include/btif_util.h
index fd16a40..075194d 100644
--- a/btif/include/btif_util.h
+++ b/btif/include/btif_util.h
@@ -102,6 +102,7 @@ int str2bd(char *str, bt_bdaddr_t *addr);
char *bd2str(bt_bdaddr_t *addr, bdstr_t *bdstr);
UINT32 devclass2uint(DEV_CLASS dev_class);
+void uint2devclass(UINT32 dev, DEV_CLASS dev_class);
void uuid16_to_uuid128(uint16_t uuid16, bt_uuid_t* uuid128);
void uuid_to_string(bt_uuid_t *p_uuid, char *str);
diff --git a/btif/src/btif_config.c b/btif/src/btif_config.c
new file mode 100644
index 0000000..8856b5a
--- /dev/null
+++ b/btif/src/btif_config.c
@@ -0,0 +1,843 @@
+/************************************************************************************
+ *
+ * Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ * This program is the proprietary software of Broadcom Corporation and/or its
+ * licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and Broadcom (an "Authorized License").
+ * Except as set forth in an Authorized License, Broadcom grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and Broadcom expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein.
+ * IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS
+ * SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+ * ALL USE OF THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of Broadcom, and you shall
+ * use all reasonable efforts to protect the confidentiality thereof,
+ * and to use this information only in connection with your use of
+ * Broadcom integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+ * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
+ * OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+ * ITS LICENSORS BE LIABLE FOR
+ * (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY
+ * DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO
+ * YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM
+ * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR
+ * (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+ * SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
+ * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF
+ * ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ ************************************************************************************/
+
+/************************************************************************************
+ *
+ * Filename: btif_config.c
+ *
+ * Description: Stores the local BT adapter and remote device properties in
+ * NVRAM storage, typically as xml file in the
+ * mobile's filesystem
+ *
+ *
+ ***********************************************************************************/
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <stdlib.h>
+
+
+#define LOG_TAG "btif_config.c"
+
+#include <hardware/bluetooth.h>
+#include "btif_config.h"
+#include "btif_config_util.h"
+#include "btif_sock_thread.h"
+#include "btif_sock_util.h"
+
+#include <cutils/log.h>
+#define info(fmt, ...) ALOGI ("%s(L%d): " fmt,__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define debug(fmt, ...) ALOGD ("%s(L%d): " fmt,__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define warn(fmt, ...) ALOGW ("## WARNING : %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define error(fmt, ...) ALOGE ("## ERROR : %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define asrt(s) if(!(s)) ALOGE ("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__)
+//#define UNIT_TEST
+#define CFG_PATH "/data/misc/bluedroid/"
+#define CFG_FILE_NAME "bt_config"
+#define CFG_FILE_EXT ".xml"
+#define CFG_FILE_EXT_OLD ".old"
+#define CFG_FILE_EXT_NEW ".new"
+#define CFG_GROW_SIZE (10*sizeof(cfg_node))
+#define GET_CHILD_MAX_COUNT(node) (short)((int)(node)->bytes / sizeof(cfg_node))
+#define IS_EMPTY(node) ((node)->name == NULL)
+#define GET_NODE_COUNT(bytes) (bytes / sizeof(cfg_node))
+#define MAX_NODE_BYTES 32000
+#define MAX_CACHED_COUNT 150
+#define CFG_CMD_SAVE 1
+
+#ifndef FALSE
+#define TRUE 1
+#define FALSE 0
+#endif
+typedef struct cfg_node_s
+{
+ const char* name;
+ union
+ {
+ struct cfg_node_s* child;
+ char* value;
+ };
+ short bytes;
+ short type;
+ short used;
+ short flag;
+} cfg_node;
+
+static pthread_mutex_t slot_lock;
+static int pth = -1; //poll thread handle
+static cfg_node root;
+static int cached_change;
+static void cfg_cmd_callback(int cmd_fd, int type, int flags, uint32_t user_id);
+static inline short alloc_node(cfg_node* p, short grow);
+static inline void free_node(cfg_node* p);
+static inline void free_inode(cfg_node* p, int child);
+static inline short find_inode(const cfg_node* p, const char* name);
+static cfg_node* find_node(const char* section, const char* key, const char* name);
+static int remove_node(const char* section, const char* key, const char* name);
+static inline cfg_node* find_free_node(cfg_node* p);
+static int set_node(const char* section, const char* key, const char* name,
+ const char* value, short bytes, short type);
+static int save_cfg();
+static void load_cfg();
+static short find_next_node(const cfg_node* p, short start, char* name, int* bytes);
+static int create_dir(const char* path);
+#ifdef UNIT_TEST
+static void cfg_test_load();
+static void cfg_test_write();
+static void cfg_test_read();
+#endif
+static inline void dump_node(const char* title, const cfg_node* p)
+{
+ if(p)
+ debug("%s, p->name:%s, child/value:%p, bytes:%d, p->used:%d, type:%x, p->flag:%d",
+ title, p->name, p->child, p->bytes, p->used, p->type, p->flag);
+ else debug("%s is NULL", title);
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+int btif_config_init()
+{
+ static int initialized;
+ debug("in initialized:%d", initialized);
+ if(!initialized)
+ {
+ initialized = 1;
+ create_dir(CFG_PATH);
+ btsock_thread_init();
+ init_slot_lock(&slot_lock);
+ lock_slot(&slot_lock);
+ root.name = "Bluedroid";
+ alloc_node(&root, CFG_GROW_SIZE);
+ dump_node("root", &root);
+ pth = btsock_thread_create(NULL, cfg_cmd_callback);
+ load_cfg();
+ unlock_slot(&slot_lock);
+ #ifdef UNIT_TEST
+ //cfg_test_load();
+ cfg_test_write();
+ cfg_test_read();
+ #endif
+ }
+ return pth >= 0;
+}
+int btif_config_get_int(const char* section, const char* key, const char* name, int* value)
+{
+ int size = sizeof(*value);
+ int type = BTIF_CFG_TYPE_INT;
+ return btif_config_get(section, key, name, (char*)value, &size, &type);
+}
+int btif_config_set_int(const char* section, const char* key, const char* name, int value)
+{
+ return btif_config_set(section, key, name, (char*)&value, sizeof(value), BTIF_CFG_TYPE_INT);
+}
+int btif_config_get_str(const char* section, const char* key, const char* name, char* value, int* size)
+{
+ int type = BTIF_CFG_TYPE_STR;
+ if(value)
+ *value = 0;
+ return btif_config_get(section, key, name, value, size, &type);
+}
+int btif_config_set_str(const char* section, const char* key, const char* name, const char* value)
+{
+ value = value ? value : "";
+ return btif_config_set(section, key, name, value, strlen(value) + 1, BTIF_CFG_TYPE_STR);
+}
+int btif_config_exist(const char* section, const char* key, const char* name)
+{
+ int ret = FALSE;
+ if(section && *section && key && *key)
+ {
+ lock_slot(&slot_lock);
+ ret = find_node(section, key, name) != NULL;
+ unlock_slot(&slot_lock);
+ }
+ return ret;
+}
+int btif_config_get(const char* section, const char* key, const char* name, char* value, int* bytes, int* type)
+{
+ //debug("in");
+
+ int ret = FALSE;
+ asrt(section && *section && key && *key && name && *name && bytes && type);
+ //debug("section:%s, key:%s, name:%s, value:%p, bytes:%d, type:%d",
+ // section, key, name, value, *bytes, *type);
+ if(section && *section && key && *key && name && *name && bytes && type)
+ {
+ lock_slot(&slot_lock);
+ const cfg_node* node = find_node(section, key, name);
+ dump_node("found node", node);
+ if(node)
+ {
+ if(*type == node->type && value && *bytes >= node->used)
+ {
+ if(node->used > 0)
+ memcpy(value, node->value, node->used);
+ ret = TRUE;
+ }
+ *type = node->type;
+ *bytes = node->used;
+ if(ret != TRUE)
+ {
+ if(*type != node->type)
+ error("value:%s, wrong type:%d, need to be type: %d", name, *type, node->type);
+ if(value && *bytes < node->used)
+ error("value:%s, not enough size: %d bytes, need %d bytes", name, node->used, *bytes);
+ }
+ }
+ unlock_slot(&slot_lock);
+ }
+ //debug("out");
+ return ret;
+}
+int btif_config_set(const char* section, const char* key, const char* name, const char* value, int bytes, int type)
+{
+ int ret = FALSE;
+ asrt(section && *section && key && *key && name && *name);
+ asrt(bytes < MAX_NODE_BYTES);
+ if(section && *section && key && *key && name && *name && bytes < MAX_NODE_BYTES)
+ {
+ lock_slot(&slot_lock);
+ ret = set_node(section, key, name, value, (short)bytes, (short)type);
+ if(ret && !(type & BTIF_CFG_TYPE_VOLATILE) && ++cached_change > MAX_CACHED_COUNT)
+ {
+ cached_change = 0;
+ btsock_thread_post_cmd(pth, CFG_CMD_SAVE, NULL, 0, 0);
+ }
+
+ unlock_slot(&slot_lock);
+ }
+ return ret;
+}
+int btif_config_remove(const char* section, const char* key, const char* name)
+{
+ asrt(section && *section && key && *key);
+ int ret = FALSE;
+ if(section && *section && key && *key)
+ {
+ lock_slot(&slot_lock);
+ ret = remove_node(section, key, name);
+ if(ret)
+ cached_change++;
+ unlock_slot(&slot_lock);
+ }
+ return ret;
+}
+typedef struct {
+ short si;
+ short ki;
+ short vi;
+ short reserved;
+} cfg_node_pos;
+short btif_config_next_key(short pos, const char* section, char * name, int* bytes)
+{
+ int next = -1;
+ lock_slot(&slot_lock);
+ short si = find_inode(&root, section);
+ if(si >= 0)
+ {
+ const cfg_node* section_node = &root.child[si];
+ next = find_next_node(section_node, pos, name, bytes);
+ }
+ unlock_slot(&slot_lock);
+ return next;
+}
+short btif_config_next_value(short pos, const char* section, const char* key, char* name, int* bytes)
+{
+ int next = -1;
+ lock_slot(&slot_lock);
+ short si = find_inode(&root, section);
+ if(si >= 0)
+ {
+ const cfg_node* section_node = &root.child[si];
+ short ki = find_inode(section_node, key);
+ if(ki >= 0)
+ {
+ const cfg_node* key_node = &section_node->child[ki];
+ next = find_next_node(key_node, pos, name, bytes);
+ }
+ }
+ unlock_slot(&slot_lock);
+ return next;
+}
+int btif_config_enum(btif_config_enum_callback cb, void* user_data)
+{
+ asrt(cb);
+ if(!cb)
+ return FALSE;
+ lock_slot(&slot_lock);
+ int si, ki, vi;
+ cfg_node *section_node, *key_node, *value_node;
+ for(si = 0; si < GET_CHILD_MAX_COUNT(&root); si++)
+ {
+ section_node = &root.child[si];
+ if(section_node->name && *section_node->name)
+ {
+ for(ki = 0; ki < GET_CHILD_MAX_COUNT(section_node); ki++)
+ {
+ key_node = &section_node->child[ki];
+ if(key_node->name && *key_node->name)
+ {
+ for(vi = 0; vi < GET_CHILD_MAX_COUNT(key_node); vi++)
+ {
+ value_node = &key_node->child[vi];
+ if(value_node->name && *value_node->name)
+ {
+ cb(user_data, section_node->name, key_node->name, value_node->name,
+ value_node->value, value_node->used, value_node->type);
+ }
+ }
+ }
+ }
+ }
+ }
+ unlock_slot(&slot_lock);
+ return TRUE;
+}
+int btif_config_save()
+{
+ lock_slot(&slot_lock);
+ if(cached_change > 0)
+ {
+ cached_change = 0;
+ btsock_thread_post_cmd(pth, CFG_CMD_SAVE, NULL, 0, 0);
+ }
+ unlock_slot(&slot_lock);
+ return TRUE;
+}
+void btif_config_flush()
+{
+ lock_slot(&slot_lock);
+ if(cached_change > 0)
+ save_cfg();
+ unlock_slot(&slot_lock);
+}
+/////////////////////////////////////////////////////////////////////////////////////////////
+static inline short alloc_node(cfg_node* p, short grow)
+{
+ int new_bytes = p->bytes + grow;
+ //debug("in, bytes:%d, new bytes:%d, grow:%d", p->bytes, new_bytes, grow);
+ if(grow > 0 && new_bytes < MAX_NODE_BYTES)
+ {
+ char* value = (char*)realloc(p->value, new_bytes);
+ if(value)
+ {
+ short old_bytes = p->bytes;
+ //clear to zero
+ memset(value + old_bytes, 0, grow);
+ p->bytes = old_bytes + grow;
+ p->value = value;
+ //debug("out");
+ return old_bytes;//return the previous size
+ }
+ else error("realloc failed, old_bytes:%d, grow:%d, total:%d", p->bytes, grow, p->bytes + grow);
+ }
+ //debug("out, alloc failed");
+ return -1;
+}
+static inline void free_node(cfg_node* p)
+{
+ if(p)
+ {
+ if(p->child)
+ {
+ free(p->child);
+ p->child = NULL;
+ }
+ if(p->name)
+ {
+ free((void*)p->name);
+ p->name = 0;
+ }
+ p->used = p->bytes = p->flag = p->type = 0;
+ }
+}
+static inline short find_inode(const cfg_node* p, const char* name)
+{
+ //debug("in");
+ if(p && p->child && name && *name)
+ {
+ int i;
+ int count = GET_CHILD_MAX_COUNT(p);
+ //debug("child name:%s, child max count:%d", name, count);
+ for(i = 0; i < count; i++)
+ {
+ if(p->child[i].name && *p->child[i].name &&
+ strcmp(p->child[i].name, name) == 0)
+ {
+ //debug("out found child index:%d", i);
+ return (short)i;
+ }
+ }
+ }
+ //debug("out, child name: %s not found", name);
+ return -1;
+}
+static inline cfg_node* find_free_node(cfg_node* p)
+{
+ if(p && p->child)
+ {
+ int i;
+ int count = GET_CHILD_MAX_COUNT(p);
+ //debug("p->name:%s, max child count:%d", p->name, count);
+ for(i = 0; i < count; i++)
+ {
+ if(IS_EMPTY(p->child + i))
+ return p->child + i;
+ }
+ }
+ return NULL;
+}
+static cfg_node* find_add_node(cfg_node* p, const char* name)
+{
+ int i = -1;
+ cfg_node* node = NULL;
+ //debug("in, p->name:%s, p->bytes:%d, adding child:%s", p->name, p->bytes, name);
+ if((i = find_inode(p, name)) < 0)
+ {
+ if(!(node = find_free_node(p)))
+ {
+ int old_size = alloc_node(p, CFG_GROW_SIZE);
+ if(old_size >= 0)
+ {
+ i = GET_NODE_COUNT(old_size);
+ node = &p->child[i];
+ }
+ }
+ }
+ else node = &p->child[i];
+ if(!node->name)
+ node->name = strdup(name);
+ //debug("out");
+ return node;
+}
+static int set_node(const char* section, const char* key, const char* name,
+ const char* value, short bytes, short type)
+{
+ int si = -1, ki = -1, vi = -1;
+ cfg_node* section_node = NULL;
+ //debug("in");
+ //dump_node("root", &root);
+ if((section_node = find_add_node(&root, section)))
+ {
+ //dump_node("section node", section_node);
+ cfg_node* key_node;
+ if((key_node = find_add_node(section_node, key)))
+ {
+ //dump_node("key node", key_node);
+ cfg_node* value_node;
+ if((value_node = find_add_node(key_node, name)))
+ {
+ //dump_node("value node", value_node);
+ if(value_node->bytes < bytes)
+ {
+ if(value_node->value)
+ free(value_node->value);
+ value_node->value = (char*)malloc(bytes);
+ if(value_node->value)
+ value_node->bytes = bytes;
+ else
+ {
+ error("not enough memory!");
+ value_node->bytes = 0;
+ return FALSE;
+ }
+ }
+ if(value_node->value && value != NULL && bytes > 0)
+ memcpy(value_node->value, value, bytes);
+ value_node->type = type;
+ value_node->used = bytes;
+ //dump_node("changed value node", value_node);
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+static cfg_node* find_node(const char* section, const char* key, const char* name)
+{
+ int si = -1, ki = -1, vi = -1;
+ if((si = find_inode(&root, section)) >= 0)
+ {
+ cfg_node* section_node = &root.child[si];
+ if(key)
+ {
+ //dump_node("found section node", section_node);
+ if((ki = find_inode(section_node, key)) >= 0)
+ {
+ cfg_node* key_node = &section_node->child[ki];
+ //dump_node("found key node", key_node);
+ if(name)
+ {
+ if((vi = find_inode(key_node, name)) >= 0)
+ {
+ //dump_node("found value node", &key_node->child[vi]);
+ return &key_node->child[vi];
+ }
+ //debug("value node:%s not found", name);
+ return NULL;
+ }
+ return key_node;
+ }
+ //debug("key node:%s not found", key);
+ return NULL;
+ }
+ return section_node;
+ }
+ //debug("section node:%s not found", section);
+ return NULL;
+}
+static short find_next_node(const cfg_node* p, short start, char* name, int* bytes)
+{
+ asrt(0 <= start && start < GET_CHILD_MAX_COUNT(p));
+ //debug("in");
+ //dump_node("parent", p);
+ short next = -1;
+ if(0 <= start && start < GET_CHILD_MAX_COUNT(p))
+ {
+ int i;
+ for(i = start; i < GET_CHILD_MAX_COUNT(p); i++)
+ {
+ cfg_node* child = &p->child[i];
+ if(child->name)
+ {
+ int name_bytes = strlen(child->name) + 1;
+ if(name && bytes && *bytes >= name_bytes)
+ {
+ memcpy(name, child->name, name_bytes);
+ if(i + 1 < GET_CHILD_MAX_COUNT(p))
+ next = (short)(i + 1);
+ *bytes = name_bytes;
+ }
+ else if(bytes)
+ {
+ //debug("not enough room to copy the name, size in:%d, size needed:%d", *bytes, name_bytes);
+ *bytes = name_bytes;
+ }
+ break;
+ }
+ }
+ }
+ return next;
+}
+static int remove_node(const char* section, const char* key, const char* name)
+{
+ short si = -1, ki = -1, vi = -1;
+ if((si = find_inode(&root, section)) >= 0)
+ {
+ cfg_node* section_node = &root.child[si];
+ if((ki = find_inode(section_node, key)) >= 0)
+ {
+ cfg_node* key_node = &section_node->child[ki];
+ if(name == NULL)
+ {
+ int count = GET_CHILD_MAX_COUNT(key_node);
+ int i;
+ for(i = 0; i < count; i++)
+ free_node(&key_node->child[i]);
+ free_node(key_node);
+ return TRUE;
+ }
+ else if((vi = find_inode(key_node, name)) >= 0)
+ {
+ //debug("remove value:%s", key_node->child[vi].name);
+ free_node(&key_node->child[vi]);
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+static int save_cfg()
+{
+ debug("in");
+ const char* file_name = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT;
+ const char* file_name_new = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT_NEW;
+ const char* file_name_old = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT_OLD;
+ int ret = FALSE;
+ if(access(file_name_old, F_OK) == 0)
+ unlink(file_name_old);
+ if(access(file_name_new, F_OK) == 0)
+ unlink(file_name_new);
+ if(btif_config_save_file(file_name_new))
+ {
+ cached_change = 0;
+ rename(file_name, file_name_old);
+ rename(file_name_new, file_name);
+ ret = TRUE;
+ }
+ else error("btif_config_save_file failed");
+ debug("out");
+ return ret;
+}
+static int load_bluez_cfg()
+{
+ char adapter_path[256];
+ if(load_bluez_adapter_info(adapter_path, sizeof(adapter_path)))
+ {
+ if(load_bluez_linkkeys(adapter_path))
+ return TRUE;
+ }
+ return FALSE;
+}
+static void remove_bluez_cfg()
+{
+ rename(BLUEZ_PATH, BLUEZ_PATH_BAK);
+}
+static void load_cfg()
+{
+ const char* file_name = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT;
+ const char* file_name_new = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT_NEW;
+ const char* file_name_old = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT_OLD;
+ if(!btif_config_load_file(file_name))
+ {
+ unlink(file_name);
+ if(!btif_config_load_file(file_name_old))
+ {
+ unlink(file_name_old);
+ if(load_bluez_cfg() && save_cfg())
+ remove_bluez_cfg();
+ }
+ }
+}
+static void cfg_cmd_callback(int cmd_fd, int type, int size, uint32_t user_id)
+{
+ debug("cmd type:%d, size:%d", type, size);
+ switch(type)
+ {
+ case CFG_CMD_SAVE:
+ lock_slot(&slot_lock);
+ save_cfg();
+ unlock_slot(&slot_lock);
+ break;
+ }
+}
+#define DIR_MODE 0740
+#define FILE_MODE 0644
+static int mk_dir(const char *path)
+{
+ struct stat st;
+
+ if (stat(path, &st) == 0)
+ {
+ if (!S_ISDIR(st.st_mode))
+ {
+ /* path is not a directory */
+ error("directory path %s is not a directory (%s)", path, strerror(errno));
+ return -1;
+ }
+
+ /* already exist */
+ return 0;
+ }
+
+ /* no existing dir path, try creating it */
+ if (mkdir(path, DIR_MODE) != 0)
+ {
+ error("failed to create dir [%s] (%s)", path, strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+static int create_dir(const char *path)
+{
+ int status = 0;
+ char tmpbuf[128];
+ char *p_copy;
+ char *p;
+
+ //debug("path: %s", path);
+
+
+ /* assumes absolute paths */
+ if (strncmp(path, "./", 2) == 0)
+ {
+ error("%s not an absolute path", path);
+ return -1;
+ }
+
+ /* try creating dir directly */
+ if (mk_dir(path) == 0)
+ return 0;
+
+ /* directory does not exit, create it */
+
+ /* first make sure we won't overflow the path buffer */
+ if ((strlen(path)+1) > sizeof(tmpbuf))
+ return -1;
+
+ /* setup scratch buffer, make sure path is ended with / */
+ sprintf(tmpbuf, "%s/", path);
+
+ p_copy = tmpbuf;
+
+ p = strchr(p_copy+1, '/'); /* skip root */
+
+ while ((status == 0) && p)
+ {
+ /*
+ * temporarily null terminate to allow creating
+ * directories up to this point
+ */
+ *p= '\0';
+ status = mk_dir(p_copy);
+ *p= '/';
+
+ /* find next */
+ p = strchr(++p, '/');
+ }
+
+ return status;
+}
+#ifdef UNIT_TEST
+static void cfg_test_load()
+{
+ load_cfg();
+ char kname[128], vname[128];
+ short kpos, vpos;
+ int kname_size, vname_size;
+ debug("in");
+ debug("list all remote devices values:");
+ kname_size = sizeof(kname);
+ kname[0] = 0;
+ kpos = 0;
+ while((kpos = btif_config_next_key(kpos, "Remote Devices", kname, &kname_size)) != -1)
+ {
+ debug("Remote devices:%s, size:%d", kname, kname_size);
+ vpos = 0;
+ vname[0] = 0;
+ vname_size = sizeof(vname);
+ while((vpos = btif_config_next_value(vpos, "Remote Devices", kname, vname, &vname_size)) != -1)
+ {
+ char v[128] = {0};
+ int vtype = BTIF_CFG_TYPE_STR;
+ int vsize = sizeof(v);
+ int ret = btif_config_get("Remote Devices", kname, vname, v, &vsize, &vtype);
+ debug("btif_config_get return:%d, Remote devices:%s, value name:%s, value:%s, value size:%d, type:0x%x",
+ ret, kname, vname, v, vsize, vtype);
+
+ vname[0] = 0;
+ vname_size = sizeof(vname);
+ }
+ kname[0] = 0;
+ kname_size = sizeof(kname);
+ }
+ debug("out");
+}
+static void cfg_test_write()
+{
+ debug("in");
+ int i;
+
+ char key[128];
+ const char* section;
+ char link_key[64];
+ for(i = 0; i < (int)sizeof(link_key); i++)
+ link_key[i] = i;
+ for(i = 0; i < 100; i++)
+ {
+ sprintf(key, "00:22:5F:97:56:%02d", i);
+ link_key[0] = i;
+ section = "Remote Devices";
+ btif_config_set_str(section, key, "class", "smart phone");
+ btif_config_set(section, key, "link keys", link_key, sizeof(link_key), BTIF_CFG_TYPE_BIN);
+ btif_config_set_int(section, key, "connect time out", i);
+ }
+ btif_config_save();
+ debug("out");
+}
+static void cfg_test_read()
+{
+ debug("in");
+ char class[128] = {0};
+ char link_key[128] = {0};
+ int size, type;
+ char key[128];
+ const char* section;
+ int ret, i;
+ for(i = 0; i < 100; i++)
+ {
+ sprintf(key, "00:22:5F:97:56:%02d", i);
+ section = "Remote Devices";
+ size = sizeof(class);
+ ret = btif_config_get_str(section, key, "class", class, &size);
+ debug("btif_config_get_str return:%d, Remote devices:%s, class:%s", ret, key, class);
+
+ size = sizeof(link_key);
+ type = BTIF_CFG_TYPE_BIN;
+ ret = btif_config_get(section, key, "link keys", link_key, &size, &type);
+ debug("btif_config_get return:%d, Remote devices:%s, link key:%x, %x",
+ ret, key, *(int *)link_key, *((int *)link_key + 1));
+
+ int timeout;
+ ret = btif_config_get_int(section, key, "connect time out", &timeout);
+ debug("btif_config_get_int return:%d, Remote devices:%s, connect time out:%d", ret, key, timeout);
+ }
+
+ debug("testing btif_config_remove");
+ size = sizeof(class);
+ type = BTIF_CFG_TYPE_STR;
+ btif_config_set("Remote Devices", "00:22:5F:97:56:04", "Class Delete", class, strlen(class) + 1, BTIF_CFG_TYPE_STR);
+
+ btif_config_get("Remote Devices", "00:22:5F:97:56:04", "Class Delete", class, &size, &type);
+ debug("Remote devices, 00:22:5F:97:56:04 Class Delete:%s", class);
+ btif_config_remove("Remote Devices", "00:22:5F:97:56:04", "Class Delete");
+
+ size = sizeof(class);
+ type = BTIF_CFG_TYPE_STR;
+ ret = btif_config_get("Remote Devices", "00:22:5F:97:56:04", "Class Delete", class, &size, &type);
+ debug("after removed, btif_config_get ret:%d, Remote devices, 00:22:5F:97:56:04 Class Delete:%s", ret, class);
+ debug("out");
+}
+#endif
diff --git a/btif/src/btif_config_util.cpp b/btif/src/btif_config_util.cpp
new file mode 100644
index 0000000..0d32da1
--- /dev/null
+++ b/btif/src/btif_config_util.cpp
@@ -0,0 +1,702 @@
+/************************************************************************************
+ *
+ * Copyright (C) 2009-2011 Broadcom Corporation
+ *
+ * This program is the proprietary software of Broadcom Corporation and/or its
+ * licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and Broadcom (an "Authorized License").
+ * Except as set forth in an Authorized License, Broadcom grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and Broadcom expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein.
+ * IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS
+ * SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+ * ALL USE OF THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of Broadcom, and you shall
+ * use all reasonable efforts to protect the confidentiality thereof,
+ * and to use this information only in connection with your use of
+ * Broadcom integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+ * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
+ * OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+ * ITS LICENSORS BE LIABLE FOR
+ * (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY
+ * DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO
+ * YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM
+ * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR
+ * (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+ * SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
+ * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF
+ * ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ ************************************************************************************/
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/vfs.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/file.h>
+#include <sys/mman.h>
+
+#include "btif_config.h"
+#include "btif_config_util.h"
+#ifndef ANDROID_NDK
+#define ANDROID_NDK
+#endif
+#include "tinyxml2.h"
+#ifndef FALSE
+#define TRUE 1
+#define FALSE 0
+#endif
+#define LOG_TAG "btif_config_util"
+extern "C" {
+#include "btif_sock_util.h"
+}
+#include <stdlib.h>
+#include <cutils/log.h>
+#define info(fmt, ...) ALOGI ("%s(L%d): " fmt,__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define debug(fmt, ...) ALOGD ("%s(L%d): " fmt,__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define warn(fmt, ...) ALOGW ("## WARNING : %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define error(fmt, ...) ALOGE ("## ERROR : %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define asrt(s) if(!(s)) ALOGE ("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__)
+
+#define BLUEDROID_ROOT "Bluedroid"
+#define BLUEDROID_NAME_TAG "Tag"
+#define BLUEDROID_VALUE_TYPE "Type"
+#define BLUEDROID_TAG_REMOTE_DEVICE "Remote Devices"
+
+using namespace tinyxml2;
+struct enum_user_data
+{
+ const char* sn; //current section name
+ const char* kn; //current key name
+ const char* vn; //current value name
+ int si, ki, vi;
+ XMLDocument* xml;
+ XMLElement* se;
+ XMLElement* ke;
+ XMLElement* ve;
+};
+
+
+static int type_str2int(const char* type);
+static const char* type_int2str(int type);
+static inline void create_ele_name(int index, char* element, int len);
+static inline int validate_ele_name(const char* key);
+static int parse_sections(const char* section_name, const XMLElement* section);
+static void enum_config(void* user_data, const char* section, const char* key, const char* name,
+ const char* value, int bytes, int type);
+static inline void bytes2hex(const char* data, int bytes, char* str)
+{
+ static const char* hex_table = "0123456789abcdef";
+ for(int i = 0; i < bytes; i++)
+ {
+ *str = hex_table[(data[i] >> 4) & 0xf];
+ ++str;
+ *str = hex_table[data[i] & 0xf];
+ ++str;
+ }
+ *str = 0;
+}
+static inline int hex2byte(char hex)
+{
+ if('0' <= hex && hex <= '9')
+ return hex - '0';
+ if('a' <= hex && hex <= 'z')
+ return hex - 'a' + 0xa;
+ if('A' <= hex && hex <= 'Z')
+ return hex - 'A' + 0xa;
+ return -1;
+}
+static inline int trim_bin_str_value(const char** str)
+{
+ while(**str == ' ' || **str == '\r' || **str == '\t' || **str == '\n')
+ (*str)++;
+ int len = 0;
+ const char* s = *str;
+ while(*s && *s != ' ' && *s != '\r' && *s != '\t' && *s != '\n')
+ {
+ len++;
+ s++;
+ }
+ return len;
+}
+static inline bool hex2bytes(const char* str, int len, char* data)
+{
+ if(len % 2)
+ {
+ error("cannot convert odd len hex str: %s, len:%d to binary", str, len);
+ return false;
+ }
+ for(int i = 0; i < len; i+= 2)
+ {
+ int d = hex2byte(str[i]);
+ if(d < 0)
+ {
+ error("cannot convert hex: %s, len:%d to binary", str, len);
+ return false;
+ }
+ *data = (char)(d << 4);
+ d = hex2byte(str[i+1]);
+ if(d < 0)
+ {
+ error("cannot convert hex: %s, len:%d to binary", str, len);
+ return false;
+ }
+ *data++ |= (char)d;
+ }
+ return true;
+}
+static inline void reverse_bin(char *bin, int size)
+{
+ for(int i = 0; i < size /2; i++)
+ {
+ int b = bin[i];
+ bin[i] = bin[size - i - 1];
+ bin[size -i - 1] = b;
+ }
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+int btif_config_save_file(const char* file_name)
+{
+ debug("in file name:%s", file_name);
+ XMLDocument xml;
+ XMLElement* root = xml.NewElement(BLUEDROID_ROOT);
+ xml.InsertFirstChild(root);
+ int ret = FALSE;
+ enum_user_data data;
+ memset(&data, 0, sizeof(data));
+ data.xml = &xml;
+ if(btif_config_enum(enum_config, &data))
+ ret = xml.SaveFile(file_name) == XML_SUCCESS;
+ return ret;
+}
+int btif_config_load_file(const char* file_name)
+{
+ //if(access(file_name, 0) != 0)
+ // return XML_ERROR_FILE_NOT_FOUND;
+ XMLDocument xml;
+ int err = xml.LoadFile(file_name);
+ const XMLElement* root = xml.RootElement();
+ int ret = FALSE;
+ if(err == XML_SUCCESS && root && strcmp(root->Name(), BLUEDROID_ROOT) == 0)
+ {
+ const XMLElement* section;
+ for(section = root->FirstChildElement(); section; section = section->NextSiblingElement())
+ {
+ //debug("section tag:%s", section->Name());
+ if(validate_ele_name(section->Name()))
+ {
+ const char* section_name = section->Attribute(BLUEDROID_NAME_TAG);
+ if(section_name && *section_name)
+ if(parse_sections(section_name, section))
+ ret = TRUE;
+ }
+ }
+ }
+ return ret;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+static int parse_sections(const char* section_name, const XMLElement* section)
+{
+ const XMLElement* key;
+ //debug("in");
+ for(key = section->FirstChildElement(); key; key = key->NextSiblingElement())
+ {
+ //debug("key tag:%s", key->Name());
+ if(validate_ele_name(key->Name()))
+ {
+ const char* key_name = key->Attribute(BLUEDROID_NAME_TAG);
+ //debug("key name:%s", key_name);
+ if(key_name && *key_name)
+ {
+ const XMLElement* value;
+ for(value = key->FirstChildElement(); value; value = value->NextSiblingElement())
+ {
+ const char* value_name = value->Attribute(BLUEDROID_NAME_TAG);
+ const char* value_type = value->Attribute(BLUEDROID_VALUE_TYPE);
+ //debug("value ele name:%s, section name:%s, key name:%s, value name:%s, value type:%s",
+ // value->Name(), section_name, key_name, value_name, value_type);
+ int type = type_str2int(value_type);
+ if(value_name && *value_name && type != BTIF_CFG_TYPE_INVALID)
+ {
+ const char* value_str = value->GetText() ? value->GetText() : "";
+ //debug("value_name:%s, value_str:%s, value_type:%s, type:%x",
+ // value_name, value_str, value_type, type);
+ if(type & BTIF_CFG_TYPE_STR)
+ btif_config_set_str(section_name, key_name, value_name, value_str);
+ else if(type & BTIF_CFG_TYPE_INT)
+ {
+ if(*value_str)
+ {
+ int v = atoi(value_str);
+ btif_config_set_int(section_name, key_name, value_name, v);
+ }
+ }
+ else if(type & BTIF_CFG_TYPE_BIN)
+ {
+ int len = trim_bin_str_value(&value_str);
+ if(len > 0 && len % 2 == 0)
+ {
+ char *bin = (char*)alloca(len / 2);
+ if(hex2bytes(value_str, len, bin))
+ btif_config_set(section_name, key_name, value_name, bin, len/2, BTIF_CFG_TYPE_BIN);
+ }
+ }
+ else error("Unsupported value:%s, type:%s not loaded", value_name, value_type);
+ }
+ }
+ }
+ }
+ }
+ //debug("out");
+ return TRUE;
+}
+static inline XMLElement* add_ele(XMLDocument* xml, XMLElement* p, int index,
+ const char* name_tag, const char* value_type = NULL)
+{
+ //debug("in, tag:%s", name_tag);
+ char ele_name[128] = {0};
+ create_ele_name(index, ele_name, sizeof(ele_name));
+ XMLElement* ele = xml->NewElement(ele_name);
+ //debug("ele name:%s, tag:%s, index:%d, value type:%s", ele_name, name_tag, index, value_type);
+ ele->SetAttribute(BLUEDROID_NAME_TAG, name_tag);
+ if(value_type && *value_type)
+ ele->SetAttribute(BLUEDROID_VALUE_TYPE, value_type);
+ p->InsertEndChild(ele);
+ //debug("out, tag:%s", name_tag);
+ return ele;
+}
+static void enum_config(void* user_data, const char* section_name, const char* key_name, const char* value_name,
+ const char* value, int bytes, int type)
+{
+ enum_user_data& d = *(enum_user_data*)user_data;
+ //debug("in, key:%s, value:%s", key_name, value_name);
+ //debug("section name:%s, key name:%s, value name:%s, value type:%s",
+ // section_name, key_name, value_name, type_int2str(type));
+ if(type & BTIF_CFG_TYPE_VOLATILE)
+ return; //skip any volatile value
+ if(d.sn != section_name)
+ {
+ d.sn = section_name;
+ d.se = add_ele(d.xml, d.xml->RootElement(), ++d.si, section_name);
+ d.ki = 0;
+ }
+ if(d.kn != key_name)
+ {
+ d.kn = key_name;
+ d.ke = add_ele(d.xml, d.se, ++d.ki, key_name);
+ d.vi = 0;
+ }
+ if(d.vn != value_name)
+ {
+ if(type & BTIF_CFG_TYPE_STR)
+ {
+ d.vn = value_name;
+ d.ve = add_ele(d.xml, d.ke, ++d.vi, value_name, type_int2str(type));
+ d.ve->InsertFirstChild(d.xml->NewText(value));
+ }
+ else if(type & BTIF_CFG_TYPE_INT)
+ {
+ d.vn = value_name;
+ d.ve = add_ele(d.xml, d.ke, ++d.vi, value_name, type_int2str(type));
+ char value_str[64] = {0};
+ snprintf(value_str, sizeof(value_str), "%d", *(int*)value);
+ d.ve->InsertFirstChild(d.xml->NewText(value_str));
+ }
+ else if(type & BTIF_CFG_TYPE_BIN)
+ {
+ d.vn = value_name;
+ d.ve = add_ele(d.xml, d.ke, ++d.vi, value_name, type_int2str(type));
+ char* value_str = (char*)alloca(bytes*2 + 1);
+ bytes2hex(value, bytes, value_str);
+ d.ve->InsertFirstChild(d.xml->NewText(value_str));
+ }
+ else error("unsupported config value name:%s, type:%s not saved", d.vn, type_int2str(type));
+ }
+ //debug("out, key:%s, value:%s", key_name, value_name);
+}
+
+static int type_str2int(const char* type)
+{
+ if(strcmp(type, "int") == 0)
+ return BTIF_CFG_TYPE_INT;
+ if(strcmp(type, "binary") == 0)
+ return BTIF_CFG_TYPE_BIN;
+ if(type == 0 || *type == 0 || strcmp(type, "string") == 0)
+ return BTIF_CFG_TYPE_STR;
+ error("unknown value type:%s", type);
+ return BTIF_CFG_TYPE_INVALID;
+}
+static const char* type_int2str(int type)
+{
+ switch(type)
+ {
+ case BTIF_CFG_TYPE_INT:
+ return "int";
+ case BTIF_CFG_TYPE_BIN:
+ return "binary";
+ case BTIF_CFG_TYPE_STR:
+ return "string";
+ default:
+ error("unknown type:%d", type);
+ break;
+ }
+ return NULL;
+}
+
+static inline void create_ele_name(int index, char* element, int len)
+{
+ snprintf(element, len, "N%d", index);
+}
+static inline int validate_ele_name(const char* key)
+{
+ //must be 'N' followed with numbers
+ if(key && *key == 'N' && *++key)
+ {
+ while(*key)
+ {
+ if(*key < '0' || *key > '9')
+ return FALSE;
+ ++key;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+static int open_file_map(const char *pathname, const char**map, int* size)
+{
+ struct stat st;
+ st.st_size = 0;
+ int fd;
+ //debug("in");
+ if((fd = open(pathname, O_RDONLY)) >= 0)
+ {
+ //debug("fd:%d", fd);
+ if(fstat(fd, &st) == 0 && st.st_size)
+ {
+ *size = st.st_size;
+ *map = (const char*)mmap(NULL, *size, PROT_READ, MAP_SHARED, fd, 0);
+ if(*map && *map != MAP_FAILED)
+ {
+ //debug("out map:%p, size:%d", *map, *size);
+ return fd;
+ }
+ }
+ close(fd);
+ }
+ //debug("out, failed");
+ return -1;
+}
+static void close_file_map(int fd, const char* map, int size)
+{
+ munmap((void*)map, size);
+ close(fd);
+}
+static int read_file_line(const char* map, int start_pos, int size, int* line_size)
+{
+ *line_size = 0;
+ //debug("in, start pos:%d, size:%d", start_pos, size);
+ int i;
+ for(i = start_pos; i < size; i++)
+ {
+ ++*line_size;
+ if(map[i] == '\r' || map[i] == '\n')
+ break;
+ }
+ //debug("out, ret:%d, start pos:%d, size:%d, line_size:%d", i, start_pos, size, *line_size);
+ return i + 1;
+}
+static const char* find_value_line(const char* map, int size, const char *key, int* value_size)
+{
+ int key_len = strlen(key);
+ int i;
+ for(i = 0; i < size; i++)
+ {
+ if(map[i] == *key)
+ {
+ if(i + key_len + 1 > size)
+ return NULL;
+ if(memcmp(map + i, key, key_len) == 0)
+ {
+ read_file_line(map, i + key_len + 1, size, value_size);
+ if(*value_size)
+ return map + i + key_len + 1;
+ break;
+ }
+ }
+ }
+ return NULL;
+}
+static int read_line_word(const char* line, int start_pos, int line_size, char* word, int *word_size, bool lower_case = false)
+{
+ int i;
+ //skip space
+ //debug("in, line start_pos:%d, line_size:%d", start_pos, line_size);
+ for(i = start_pos; i < line_size; i++)
+ {
+ //debug("skip space loop, line[%d]:%c", i, line[i]);
+ if(line[i] != ' ' && line[i] != '\t' && line[i] != '\r' && line[i] !='\n')
+ break;
+ }
+ *word_size = 0;
+ for(; i < line_size; i++)
+ {
+ //debug("add word loop, line[%d]:%c", i, line[i]);
+ if(line[i] != ' ' && line[i] != '\t' && line[i] != '\r' && line[i] !='\n')
+ {
+ ++*word_size;
+ if(lower_case && 'A' <= line[i] && line[i] <= 'Z')
+ *word++ = 'a' - 'A' + line[i];
+ else
+ *word++ = line[i];
+ }
+ else break;
+ }
+ *word = 0;
+ //debug("out, ret:%d, word:%s, word_size:%d, line start_pos:%d, line_size:%d",
+ // i, word, *word_size, start_pos, line_size);
+ return i;
+}
+static int is_valid_bd_addr(const char* addr)
+{
+ int len = strlen(addr);
+ //debug("addr: %s, len:%d", addr, len);
+ return len == 17 && addr[2] == ':' && addr[5] == ':' && addr[14] == ':';
+}
+static int load_bluez_cfg_value(const char* adapter_path, const char* file_name)
+{
+ //debug("in");
+
+ const char* map = NULL;
+ int size = 0;
+ int ret = FALSE;
+ char path[256];
+ snprintf(path, sizeof(path), "%s/%s", adapter_path, file_name);
+ int fd = open_file_map(path, &map, &size);
+ //debug("in, path:%s, fd:%d, size:%d", path, fd, size);
+ if(fd < 0 || size == 0)
+ {
+ error("open_file_map fail, fd:%d, path:%s, size:%d", fd, path, size);
+ //debug("out");
+ return FALSE;
+ }
+ //get local bt device name from bluez config
+ int line_size = 0;
+ const char *value_line = find_value_line(map, size, "name", &line_size);
+ if(value_line && line_size > 0)
+ {
+ char value[line_size + 1];
+ memcpy(value, value_line, line_size);
+ value[line_size] = 0;
+ //debug("import local bt dev names:%s", value);
+ btif_config_set_str("Local", "Adapter", "Name", value);
+ ret = TRUE;
+ }
+
+ close_file_map(fd, map, size);
+ //debug("out, ret:%d", ret);
+ return ret;
+}
+
+int load_bluez_adapter_info(char* adapter_path, int size)
+{
+ struct dirent *dptr;
+ DIR *dirp;
+ int ret = FALSE;
+ if((dirp = opendir(BLUEZ_PATH)) != NULL)
+ {
+ while((dptr = readdir(dirp)) != NULL)
+ {
+ //debug("readdir: %s",dptr->d_name);
+ if(is_valid_bd_addr(dptr->d_name))
+ {
+ snprintf(adapter_path, size, "%s%s", BLUEZ_PATH, dptr->d_name);
+ btif_config_set_str("Local", "Adapter", "Address", dptr->d_name);
+ load_bluez_cfg_value(adapter_path, BLUEZ_CONFIG);
+ ret = TRUE;
+ break;
+ }
+ }
+ closedir(dirp);
+ }
+ return ret;
+}
+static inline void upcase_addr(const char* laddr, char* uaddr, int size)
+{
+ int i;
+ for(i = 0; i < size && laddr[i]; i++)
+ uaddr[i] = ('a' <= laddr[i] && laddr[i] <= 'z') ?
+ laddr[i] - ('a' - 'A') : laddr[i];
+ uaddr[i] = 0;
+}
+static int load_bluez_dev_value(const char* adapter_path, const char* bd_addr,
+ const char* file_name, const char* cfg_value_name, int type)
+{
+ //debug("in");
+ char addr[32];
+ upcase_addr(bd_addr, addr, sizeof(addr));
+
+ const char* map = NULL;
+ int size = 0;
+ int ret = FALSE;
+ char path[256];
+ snprintf(path, sizeof(path), "%s/%s", adapter_path, file_name);
+ int fd = open_file_map(path, &map, &size);
+ //debug("in, path:%s, addr:%s, fd:%d, size:%d", path, addr, fd, size);
+ if(fd < 0 || size == 0)
+ {
+ error("open_file_map fail, fd:%d, path:%s, size:%d", fd, path, size);
+ //debug("out");
+ return FALSE;
+ }
+ int line_size = 0;
+ const char *value_line = find_value_line(map, size, addr, &line_size);
+ if(value_line && line_size)
+ {
+ char line[line_size + 1];
+ memcpy(line, value_line, line_size);
+ line[line_size] = 0;
+ //debug("addr:%s, Names:%s", bd_addr, line);
+ if(type == BTIF_CFG_TYPE_STR)
+ btif_config_set_str("Remote", bd_addr, cfg_value_name, line);
+ else if(type == BTIF_CFG_TYPE_INT)
+ {
+ int v = strtol(line, NULL, 16);
+ //filter out unspported devices by its class
+ if(strcmp(file_name, BLUEZ_CLASSES) == 0)
+ {
+ switch((v & 0x1f00) >> 8)
+ {
+ case 0x5: //hid device
+ error("skip paired hid devices");
+ close_file_map(fd, map, size);
+ return FALSE;
+ }
+ }
+ btif_config_set_int("Remote", bd_addr, cfg_value_name, v);
+ }
+ ret = TRUE;
+ }
+ close_file_map(fd, map, size);
+ //debug("out, ret:%d", ret);
+ return ret;
+}
+static inline int bz2bd_linkkeytype(int type)
+{
+#if 1
+ return type;
+#else
+ int table[5] = {0, 0, 0, 0, 0};
+ if(0 <= type && type < (int)(sizeof(table)/sizeof(int)))
+ return table[type];
+ return 0;
+#endif
+}
+int load_bluez_linkkeys(const char* adapter_path)
+{
+ const char* map = NULL;
+ int size = 0;
+ int ret = FALSE;
+ char path[256];
+ //debug("in");
+ snprintf(path, sizeof(path), "%s/%s", adapter_path, BLUEZ_LINKKEY);
+ int fd = open_file_map(path, &map, &size);
+ if(fd < 0 || size == 0)
+ {
+ error("open_file_map fail, fd:%d, path:%s, size:%d", fd, path, size);
+ //debug("out");
+ return FALSE;
+ }
+ int pos = 0;
+ //debug("path:%s, size:%d", path, size);
+ while(pos < size)
+ {
+ int line_size = 0;
+ int next_pos = read_file_line(map, pos, size, &line_size);
+ //debug("pos:%d, next_pos:%d, size:%d, line_size:%d", pos, next_pos, size, line_size);
+ if(line_size)
+ {
+ const char* line = map + pos;
+ char addr[line_size + 1];
+ int word_pos = 0;
+ int addr_size = 0;
+ word_pos = read_line_word(line, word_pos, line_size, addr, &addr_size, true);
+ //debug("read_line_word addr:%s, addr_size:%d", addr, addr_size);
+ if(*addr)
+ {
+ char value[line_size + 1];
+ int value_size = 0;
+ //read link key
+ word_pos = read_line_word(line, word_pos, line_size, value, &value_size);
+ //debug("read_line_word linkkey:%s, size:%d", value, value_size);
+ if(*value)
+ {
+ int linkkey_size = value_size / 2;
+ char linkkey[linkkey_size];
+ if(hex2bytes(value, value_size, linkkey))
+ { //read link key type
+ //bluez save the linkkey in reversed order
+ reverse_bin(linkkey, linkkey_size);
+ word_pos = read_line_word(line, word_pos,
+ line_size, value, &value_size);
+ if(*value)
+ {
+ if(load_bluez_dev_value(adapter_path, addr,
+ BLUEZ_CLASSES, "DevClass", BTIF_CFG_TYPE_INT) &&
+ load_bluez_dev_value(adapter_path, addr,
+ BLUEZ_NAMES, "Name", BTIF_CFG_TYPE_STR) &&
+ load_bluez_dev_value(adapter_path, addr,
+ BLUEZ_TYPES, "DevType", BTIF_CFG_TYPE_INT) &&
+ load_bluez_dev_value(adapter_path, addr,
+ BLUEZ_PROFILES, "Service", BTIF_CFG_TYPE_STR))
+ {
+ load_bluez_dev_value(adapter_path, addr,
+ BLUEZ_ALIASES, "Aliase", BTIF_CFG_TYPE_STR);
+ int key_type = bz2bd_linkkeytype(atoi(value));
+
+ //read pin len
+ word_pos = read_line_word(line, word_pos, line_size, value, &value_size);
+ if(*value)
+ {
+ int pin_len = atoi(value);
+ ret = TRUE;
+ btif_config_set("Remote", addr, "LinkKey", linkkey,
+ linkkey_size, BTIF_CFG_TYPE_BIN);
+ //dump_bin("import bluez linkkey", linkkey, linkkey_size);
+ btif_config_set_int("Remote", addr, "LinkKeyType", key_type);
+ btif_config_set_int("Remote", addr, "PinLength", pin_len);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ //debug("pos:%d, next_pos:%d, size:%d, line_size:%d", pos, next_pos, size, line_size);
+ pos = next_pos;
+ }
+ close_file_map(fd, map, size);
+ //debug("out, ret:%d", ret);
+ return ret;
+}
+
diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c
index 032ddf0..555326a 100755
--- a/btif/src/btif_core.c
+++ b/btif/src/btif_core.c
@@ -77,7 +77,7 @@
#include "btif_sock.h"
#include "btif_pan.h"
#include "btif_profile_queue.h"
-
+#include "btif_config.h"
/************************************************************************************
** Constants & Macros
************************************************************************************/
@@ -374,6 +374,13 @@ static void btif_fetch_local_bdaddr(bt_bdaddr_t *local_addr)
const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0};
BTIF_TRACE_DEBUG1("Look for bdaddr storage path in prop %s", PROPERTY_BT_BDADDR_PATH);
+ int val_size = sizeof(val);
+ if(btif_config_get_str("Local", "Adapter", "Address", val, &val_size))
+ {
+ str2bd(val, local_addr);
+ BTIF_TRACE_DEBUG1("local bdaddr from bt_config.xml is %s", val);
+ return;
+ }
/* Get local bdaddr storage path from property */
if (property_get(PROPERTY_BT_BDADDR_PATH, val, NULL))
@@ -435,6 +442,11 @@ static void btif_fetch_local_bdaddr(bt_bdaddr_t *local_addr)
if (property_set(PERSIST_BDADDR_PROPERTY, (char*)bdstr) < 0)
BTIF_TRACE_ERROR1("Failed to set random BDA in prop %s",PERSIST_BDADDR_PROPERTY);
}
+ //save the bd address to config file
+ bdstr_t bdstr;
+ bd2str(local_addr, &bdstr);
+ btif_config_set_str("Local", "Adapter", "Address", bdstr);
+ btif_config_save();
}
/*****************************************************************************
@@ -456,7 +468,7 @@ static void btif_fetch_local_bdaddr(bt_bdaddr_t *local_addr)
bt_status_t btif_init_bluetooth()
{
UINT8 status;
-
+ btif_config_init();
bte_main_boot_entry();
/* As part of the init, fetch the local BD ADDR */
@@ -618,6 +630,8 @@ bt_status_t btif_disable_bluetooth(void)
status = BTA_DisableBluetooth();
+ btif_config_flush();
+
if (status != BTA_SUCCESS)
{
BTIF_TRACE_ERROR1("disable bt failed (%d)", status);
diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c
index d31e1ca..31b6435 100755
--- a/btif/src/btif_dm.c
+++ b/btif/src/btif_dm.c
@@ -830,7 +830,7 @@ static void btif_dm_search_devices_evt (UINT16 event, char *p_param)
properties[0].type = BT_PROPERTY_BDNAME;
properties[0].val = p_search_data->disc_res.bd_name;
- properties[0].len = strlen((char *)p_search_data->disc_res.bd_name)+1;
+ properties[0].len = strlen((char *)p_search_data->disc_res.bd_name);
bdcpy(bdaddr.address, p_search_data->disc_res.bd_addr);
status = btif_storage_set_remote_device_property(&bdaddr, &properties[0]);
@@ -900,7 +900,7 @@ static void btif_dm_search_devices_evt (UINT16 event, char *p_param)
if (bdname.name[0]) {
BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties],
BT_PROPERTY_BDNAME,
- strlen((char *)bdname.name)+1, &bdname);
+ strlen((char *)bdname.name), &bdname);
num_properties++;
}
diff --git a/btif/src/btif_pan.c b/btif/src/btif_pan.c
index 8484bb8..c9cd6a7 100644
--- a/btif/src/btif_pan.c
+++ b/btif/src/btif_pan.c
@@ -313,7 +313,7 @@ void create_tap_read_thread(int tap_fd)
debug("in");
if(pth < 0)
{
- pth = btsock_thread_create(btpan_tap_fd_signaled);
+ pth = btsock_thread_create(btpan_tap_fd_signaled, NULL);
if(pth >= 0)
btsock_thread_add_fd(pth, tap_fd, 0, SOCK_THREAD_FD_RD, 0);
}
diff --git a/btif/src/btif_sock.c b/btif/src/btif_sock.c
index a687553..553a1bb 100644
--- a/btif/src/btif_sock.c
+++ b/btif/src/btif_sock.c
@@ -110,7 +110,7 @@ bt_status_t btif_sock_init()
//binit = 1;
debug("btsock initializing...");
btsock_thread_init();
- int handle = btsock_thread_create(btsock_signaled);
+ int handle = btsock_thread_create(btsock_signaled, NULL);
if(handle >= 0 && btsock_rfc_init(handle) == BT_STATUS_SUCCESS)
{
debug("btsock successfully initialized");
diff --git a/btif/src/btif_sock_thread.c b/btif/src/btif_sock_thread.c
index 85690c3..173f20f 100644
--- a/btif/src/btif_sock_thread.c
+++ b/btif/src/btif_sock_thread.c
@@ -75,6 +75,7 @@
#include <sys/select.h>
#include <sys/poll.h>
#include <cutils/sockets.h>
+#include <alloca.h>
#define LOG_TAG "BTIF_SOCK"
#include "btif_common.h"
@@ -110,9 +111,10 @@
#define IS_READ(e) ((e) & POLLIN)
#define IS_WRITE(e) ((e) & POLLOUT)
/*cmd executes in socket poll thread */
-#define CMD_WAKEUP 1
-#define CMD_EXIT 2
-#define CMD_ADD_FD 3
+#define CMD_WAKEUP 1
+#define CMD_EXIT 2
+#define CMD_ADD_FD 3
+#define CMD_USER_PRIVATE 4
typedef struct {
struct pollfd pfd;
@@ -127,6 +129,7 @@ typedef struct {
int psi[MAX_POLL]; //index of poll slot
volatile pid_t thread_id;
btsock_signaled_cb callback;
+ btsock_cmd_cb cmd_callback;
int used;
} thread_slot_t;
static thread_slot_t ts[MAX_THREAD];
@@ -231,23 +234,29 @@ static void free_thread_slot(int h)
}
int btsock_thread_init()
{
- debug("in");
- init_slot_lock(&thread_slot_lock);
- int h;
- for(h = 0; h < MAX_THREAD; h++)
+ static int initialized;
+ debug("in initialized:%d", initialized);
+ if(!initialized)
{
- ts[h].cmd_fdr = ts[h].cmd_fdw = -1;
- ts[h].used = 0;
- ts[h].thread_id = -1;
- ts[h].poll_count = 0;
- ts[h].callback = NULL;
+ initialized = 1;
+ init_slot_lock(&thread_slot_lock);
+ int h;
+ for(h = 0; h < MAX_THREAD; h++)
+ {
+ ts[h].cmd_fdr = ts[h].cmd_fdw = -1;
+ ts[h].used = 0;
+ ts[h].thread_id = -1;
+ ts[h].poll_count = 0;
+ ts[h].callback = NULL;
+ ts[h].cmd_callback = NULL;
+ }
}
return TRUE;
}
-int btsock_thread_create(btsock_signaled_cb callback)
+int btsock_thread_create(btsock_signaled_cb callback, btsock_cmd_cb cmd_callback)
{
int ret = FALSE;
- asrt(callback);
+ asrt(callback || cmd_callback);
lock_slot(&thread_slot_lock);
int h = alloc_thread_slot();
unlock_slot(&thread_slot_lock);
@@ -259,6 +268,7 @@ int btsock_thread_create(btsock_signaled_cb callback)
{
debug("h:%d, thread id:%d", h, ts[h].thread_id);
ts[h].callback = callback;
+ ts[h].cmd_callback = cmd_callback;
}
else
{
@@ -331,7 +341,39 @@ int btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id)
debug("adding fd:%d, flags:0x%x", fd, flags);
return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd);
}
-
+int btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size, uint32_t user_id)
+{
+ if(h < 0 || h >= MAX_THREAD)
+ {
+ error("invalid bt thread handle:%d", h);
+ return FALSE;
+ }
+ if(ts[h].cmd_fdw == -1)
+ {
+ error("cmd socket is not created. socket thread may not initialized");
+ return FALSE;
+ }
+ sock_cmd_t cmd = {CMD_USER_PRIVATE, 0, type, size, user_id};
+ debug("post cmd type:%d, size:%d, h:%d, ", type, size, h);
+ sock_cmd_t* cmd_send = &cmd;
+ int size_send = sizeof(cmd);
+ if(data && size)
+ {
+ size_send = sizeof(cmd) + size;
+ cmd_send = (sock_cmd_t*)alloca(size_send);
+ if(cmd_send)
+ {
+ *cmd_send = cmd;
+ memcpy(cmd_send + 1, data, size);
+ }
+ else
+ {
+ error("alloca failed at h:%d, cmd type:%d, size:%d", h, type, size_send);
+ return FALSE;
+ }
+ }
+ return send(ts[h].cmd_fdw, cmd_send, size_send, 0) == size_send;
+}
int btsock_thread_wakeup(int h)
{
if(h < 0 || h >= MAX_THREAD)
@@ -376,6 +418,7 @@ static void init_poll(int h)
ts[h].poll_count = 0;
ts[h].thread_id = -1;
ts[h].callback = NULL;
+ ts[h].cmd_callback = NULL;
for(i = 0; i < MAX_POLL; i++)
{
ts[h].ps[i].pfd.fd = -1;
@@ -477,6 +520,12 @@ static int process_cmd_sock(int h)
case CMD_WAKEUP:
debug("CMD_WAKEUP");
break;
+ case CMD_USER_PRIVATE:
+ debug("CMD_USER_PRIVATE");
+ asrt(ts[h].cmd_callback);
+ if(ts[h].cmd_callback)
+ ts[h].cmd_callback(fd, cmd.type, cmd.flags, cmd.user_id);
+ break;
case CMD_EXIT:
debug("CMD_EXIT");
return FALSE;
diff --git a/btif/src/btif_storage.c b/btif/src/btif_storage.c
index 4d80914..0110d04 100755
--- a/btif/src/btif_storage.c
+++ b/btif/src/btif_storage.c
@@ -50,60 +50,20 @@
* Filename: btif_storage.c
*
* Description: Stores the local BT adapter and remote device properties in
- * NVRAM storage, typically as text files in the
+ * NVRAM storage, typically as xml file in the
* mobile's filesystem
*
*
- * Data storage directory structure
- *
- * data
- * `-- misc
- * `-- bluedroid
- * `-- LOCAL
- * |-- adapter_info - Local adapter config
- * |-- remote_devices - Remote devices and Timestamp
- * |-- remote_devclass - Remote devices' COD
- * |-- remote_devtype - Remote devices' type
- * |-- remote_names - Remote devices' names
- * |-- remote_aliases - Remote devices' Friendly names
- * `-- remote_services - Remote devices' services
- *
- *
- * adapter_info - Key/Value
- * name <space> <Name of Local Bluetooth device>
- * scan_mode <space> <Scan Mode>
- * discovery_timeout <space> <Discovery Timeout in seconds>
- *
- * remote_devices - Key/Value
- * <remote device bd_addr> <space> <Timestamp>
- *
- * remote_devclass - Key/Value
- * <remote device bd_addr> <space> <Device class>
- *
- * remote_devtype - Key/Value
- * <remote_device bd_addr><space> <Device Type>
- *
- * remote_names - Key/Value
- * <remote_device bd_addr> <space> <Bluetooth device Name as reported by the controller>
- *
- * remote_linkkeys - Key/Value
- * <remote device bd_addr > <space> <LinkKey> <space> <KeyType> <space> <PinLength>
- *
- * remote_aliases - Key/Value
- * <remote device bd_addr> <space> <Friendy Name>
- *
- * remote_services - Key/Value
- * <remote_device bd_addr> <space> <List of UUIDs separated by semicolons>
- *
- ***********************************************************************************/
+ */
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
+#include <alloca.h>
#include <hardware/bluetooth.h>
-
+#include "btif_config.h"
#define LOG_TAG "BTIF_STORAGE"
#include "btif_api.h"
@@ -115,6 +75,12 @@
#include "bta_hh_api.h"
#include "btif_hh.h"
+#include <cutils/log.h>
+#define info(fmt, ...) ALOGI ("%s(L%d): " fmt,__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define debug(fmt, ...) ALOGD ("%s(L%d): " fmt,__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define warn(fmt, ...) ALOGW ("## WARNING : %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define error(fmt, ...) ALOGE ("## ERROR : %s(L%d): " fmt "##",__FUNCTION__, __LINE__, ## __VA_ARGS__)
+#define asrt(s) if(!(s)) ALOGE ("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__)
/************************************************************************************
** Constants & Macros
@@ -122,23 +88,23 @@
#define BTIF_STORAGE_PATH_BLUEDROID "/data/misc/bluedroid"
-#define BTIF_STORAGE_PATH_ADAPTER_INFO "adapter_info"
-#define BTIF_STORAGE_PATH_REMOTE_DEVICES "remote_devices"
-#define BTIF_STORAGE_PATH_REMOTE_DEVCLASSES "remote_devclasses"
-#define BTIF_STORAGE_PATH_REMOTE_DEVTYPES "remote_devtypes"
-#define BTIF_STORAGE_PATH_REMOTE_NAMES "remote_names"
-#define BTIF_STORAGE_PATH_REMOTE_LINKKEYS "remote_linkkeys"
-#define BTIF_STORAGE_PATH_REMOTE_ALIASES "remote_aliases"
-#define BTIF_STORAGE_PATH_REMOTE_SERVICES "remote_services"
-#define BTIF_STORAGE_PATH_REMOTE_HIDINFO "hid_info"
-#define BTIF_STORAGE_PATH_DYNAMIC_AUTOPAIR_BLACKLIST ""
-#define BTIF_STORAGE_KEY_ADAPTER_NAME "name"
-#define BTIF_STORAGE_KEY_ADAPTER_SCANMODE "scan_mode"
-#define BTIF_STORAGE_KEY_ADAPTER_DISC_TIMEOUT "discovery_timeout"
+//#define BTIF_STORAGE_PATH_ADAPTER_INFO "adapter_info"
+//#define BTIF_STORAGE_PATH_REMOTE_DEVICES "remote_devices"
+#define BTIF_STORAGE_PATH_REMOTE_DEVTIME "Timestamp"
+#define BTIF_STORAGE_PATH_REMOTE_DEVCLASS "DevClass"
+#define BTIF_STORAGE_PATH_REMOTE_DEVTYPE "DevType"
+#define BTIF_STORAGE_PATH_REMOTE_NAME "Name"
+//#define BTIF_STORAGE_PATH_REMOTE_LINKKEYS "remote_linkkeys"
+#define BTIF_STORAGE_PATH_REMOTE_ALIASE "Aliase"
+#define BTIF_STORAGE_PATH_REMOTE_SERVICE "Service"
+#define BTIF_STORAGE_PATH_REMOTE_HIDINFO "HidInfo"
+#define BTIF_STORAGE_KEY_ADAPTER_NAME "Name"
+#define BTIF_STORAGE_KEY_ADAPTER_SCANMODE "ScanMode"
+#define BTIF_STORAGE_KEY_ADAPTER_DISC_TIMEOUT "DiscoveryTimeout"
#define BTIF_AUTO_PAIR_CONF_FILE "/etc/bluetooth/auto_pair_devlist.conf"
-#define BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST "auto_pair_blacklist"
+#define BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST "AutoPairBlacklist"
#define BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_ADDR "AddressBlacklist"
#define BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_EXACTNAME "ExactNameBlacklist"
#define BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_PARTIALNAME "PartialNameBlacklist"
@@ -264,33 +230,6 @@ static char* btif_in_make_filename(bt_bdaddr_t *bd_addr, char *fname)
return(char*)path;
}
-
-/*******************************************************************************
-**
-** Function btif_in_adapter_key_from_type
-**
-** Description Internal helper function to map a property type
-** to the NVRAM filename key
-**
-** Returns NVRAM filename key if successfull, 'NO_KEY' otherwise
-**
-*******************************************************************************/
-static const char *btif_in_get_adapter_key_from_type(bt_property_type_t type)
-{
- switch (type)
- {
- case BT_PROPERTY_BDNAME:
- return BTIF_STORAGE_KEY_ADAPTER_NAME;
- case BT_PROPERTY_ADAPTER_SCAN_MODE:
- return BTIF_STORAGE_KEY_ADAPTER_SCANMODE;
- case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
- return BTIF_STORAGE_KEY_ADAPTER_DISC_TIMEOUT;
- default:
- /* return valid string to avoid passing NULL to NV RAM driver */
- return "NO_KEY";
- }
-}
-
/*******************************************************************************
**
** Function btif_in_split_uuids_string_to_list
@@ -310,7 +249,8 @@ static void btif_in_split_uuids_string_to_list(char *str, bt_uuid_t *p_uuid,
uint32_t num = 0;
do
{
- p_needle = strchr(p_start, ';');
+ //p_needle = strchr(p_start, ';');
+ p_needle = strchr(p_start, ' ');
if (p_needle < p_start) break;
memset(buf, 0, sizeof(buf));
strncpy(buf, p_start, (p_needle-p_start));
@@ -321,286 +261,163 @@ static void btif_in_split_uuids_string_to_list(char *str, bt_uuid_t *p_uuid,
} while (*p_start != 0);
*p_num_uuid = num;
}
-
-/*******************************************************************************
-**
-** Function btif_in_str_to_property
-**
-** Description Internal helper function to convert the string read from
-** NVRAM into a property->val. Also sets the property->len.
-** Assumption is that property->val has enough memory to
-** store the string fetched from NVRAM
-**
-** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
-**
-*******************************************************************************/
-static bt_status_t btif_in_str_to_property(char *value, bt_property_t *property)
+static int prop2cfg(bt_bdaddr_t *remote_bd_addr, bt_property_t *prop)
{
- bt_status_t status = BT_STATUS_SUCCESS;
- property->len = 0;
-
- /* if Value is NULL, then just set the property->len to 0 and return.
- This is possible if the entry does not exist */
- if (value == NULL)
- {
- status = BT_STATUS_FAIL;
- }
- switch (property->type)
- {
+ bdstr_t bdstr = {0};
+ if(remote_bd_addr)
+ bd2str(remote_bd_addr, &bdstr);
+ debug("in, bd addr:%s, prop type:%d, len:%d", bdstr, prop->type, prop->len);
+ char value[1024];
+ if(prop->len <= 0 || prop->len > (int)sizeof(value) - 1)
+ {
+ error("property type:%d, len:%d is invalid", prop->type, prop->len);
+ return FALSE;
+ }
+ switch(prop->type)
+ {
+ case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
+ btif_config_set_int("Remote", bdstr,
+ BTIF_STORAGE_PATH_REMOTE_DEVTIME, (int)time(NULL));
+ break;
case BT_PROPERTY_BDNAME:
+ strncpy(value, (char*)prop->val, prop->len);
+ value[prop->len]='\0';
+ btif_config_set_str("Remote", bdstr,
+ BTIF_STORAGE_PATH_REMOTE_NAME, value);
+ break;
case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
- {
- *((char*)property->val) = 0;
- if (value)
- {
- property->len = strlen(value);
- strcpy((char*)property->val, value);
- }
- } break;
+ strncpy(value, (char*)prop->val, prop->len);
+ value[prop->len]='\0';
+ btif_config_set_str("Remote", bdstr, BTIF_STORAGE_PATH_REMOTE_ALIASE, value);
+ break;
case BT_PROPERTY_ADAPTER_SCAN_MODE:
+ btif_config_set_int("Local", "Adapter",
+ BTIF_STORAGE_KEY_ADAPTER_SCANMODE, *(int*)prop->val);
+ break;
case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
- {
- *((uint32_t *)property->val) = 0;
- if (value)
- {
- uint32_t ival;
- property->len = sizeof(uint32_t);
- ival = atoi(value);
- memcpy((uint32_t*)property->val, &ival, sizeof(uint32_t));
- }
- } break;
+ btif_config_set_int("Local", "Adapter",
+ BTIF_STORAGE_KEY_ADAPTER_DISC_TIMEOUT, *(int*)prop->val);
+ break;
case BT_PROPERTY_CLASS_OF_DEVICE:
+ btif_config_set_int("Remote", bdstr,
+ BTIF_STORAGE_PATH_REMOTE_DEVCLASS, *(int*)prop->val);
+ break;
case BT_PROPERTY_TYPE_OF_DEVICE:
- {
- *((uint32_t *)property->val) = 0;
- if (value)
- {
- uint32_t ival;
- property->len = sizeof(uint32_t);
- ival = strtol(value, NULL, 16);
- memcpy((uint32_t*)property->val, &ival, sizeof(uint32_t));
- }
- } break;
+ btif_config_set_int("Remote", bdstr,
+ BTIF_STORAGE_PATH_REMOTE_DEVTYPE, *(int*)prop->val);
+ break;
case BT_PROPERTY_UUIDS:
+ {
+ uint32_t i;
+ char buf[64];
+ value[0] = 0;
+ for (i=0; i < (prop->len)/sizeof(bt_uuid_t); i++)
{
- if (value)
- {
- bt_uuid_t *p_uuid = (bt_uuid_t*)property->val;
- uint32_t num_uuids = 0;
- btif_in_split_uuids_string_to_list(value, p_uuid, &num_uuids);
- property->len = num_uuids * sizeof(bt_uuid_t);
- }
- } break;
- default:
- {
- break;
+ bt_uuid_t *p_uuid = (bt_uuid_t*)prop->val + i;
+ memset(buf, 0, sizeof(buf));
+ uuid_to_string(p_uuid, buf);
+ strcat(value, buf);
+ //strcat(value, ";");
+ strcat(value, " ");
}
+ btif_config_set_str("Remote", bdstr, BTIF_STORAGE_PATH_REMOTE_SERVICE, value);
+ break;
+ }
+ default:
+ error("Unknow prop type:%d", prop->type);
+ return FALSE;
}
- return status;
+ return TRUE;
}
-
-/*******************************************************************************
-**
-** Function btif_in_property_to_str
-**
-** Description Internal helper function to convert the property->val
-** to a string that can be written to the NVRAM
-**
-** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
-**
-*******************************************************************************/
-static bt_status_t btif_in_property_to_str(bt_property_t *property, char *value)
+static int cfg2prop(bt_bdaddr_t *remote_bd_addr, bt_property_t *prop)
{
- switch (property->type)
- {
- case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
- {
- sprintf(value, "%d", (int)time(NULL));
- }break;
+ bdstr_t bdstr = {0};
+ if(remote_bd_addr)
+ bd2str(remote_bd_addr, &bdstr);
+ debug("in, bd addr:%s, prop type:%d, len:%d", bdstr, prop->type, prop->len);
+ if(prop->len <= 0)
+ {
+ error("property type:%d, len:%d is invalid", prop->type, prop->len);
+ return FALSE;
+ }
+ int ret = FALSE;
+ switch(prop->type)
+ {
+ case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
+ if(prop->len >= (int)sizeof(int))
+ ret = btif_config_get_int("Remote", bdstr,
+ BTIF_STORAGE_PATH_REMOTE_DEVTIME, (int*)prop->val);
+ break;
case BT_PROPERTY_BDNAME:
+ {
+ int len = prop->len;
+ ret = btif_config_get_str("Remote", bdstr,
+ BTIF_STORAGE_PATH_REMOTE_NAME, (char*)prop->val, &len);
+ if(ret && len && len <= prop->len)
+ prop->len = len - 1;
+ else
+ {
+ prop->len = 0;
+ ret = FALSE;
+ }
+ break;
+ }
case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
+ {
+ int len = prop->len;
+ ret = btif_config_get_str("Remote", bdstr,
+ BTIF_STORAGE_PATH_REMOTE_ALIASE, (char*)prop->val, &len);
+ if(ret && len && len <= prop->len)
+ prop->len = len - 1;
+ else
{
- strncpy(value, (char*)property->val, property->len);
- value[property->len]='\0';
- }break;
+ prop->len = 0;
+ ret = FALSE;
+ }
+ break;
+ }
case BT_PROPERTY_ADAPTER_SCAN_MODE:
+ if(prop->len >= (int)sizeof(int))
+ ret = btif_config_get_int("Local", "Adapter",
+ BTIF_STORAGE_KEY_ADAPTER_SCANMODE, (int*)prop->val);
+ break;
case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
- {
- sprintf(value, "%d", *((uint32_t*)property->val));
- }break;
+ if(prop->len >= (int)sizeof(int))
+ ret = btif_config_get_int("Local", "Adapter",
+ BTIF_STORAGE_KEY_ADAPTER_DISC_TIMEOUT, (int*)prop->val);
+ break;
case BT_PROPERTY_CLASS_OF_DEVICE:
+ if(prop->len >= (int)sizeof(int))
+ ret = btif_config_get_int("Remote", bdstr,
+ BTIF_STORAGE_PATH_REMOTE_DEVCLASS, (int*)prop->val);
+ break;
case BT_PROPERTY_TYPE_OF_DEVICE:
- {
- sprintf(value, "0x%x", *((uint32_t*)property->val));
- }break;
+ if(prop->len >= (int)sizeof(int))
+ ret = btif_config_get_int("Remote",
+ bdstr, BTIF_STORAGE_PATH_REMOTE_DEVTYPE, (int*)prop->val);
+ break;
case BT_PROPERTY_UUIDS:
+ {
+ char value[1280];
+ int size = sizeof(value);
+ if(btif_config_get_str("Remote", bdstr,
+ BTIF_STORAGE_PATH_REMOTE_SERVICE, value, &size))
{
- uint32_t i;
- char buf[64];
- value[0] = 0;
- for (i=0; i < (property->len)/sizeof(bt_uuid_t); i++)
- {
- bt_uuid_t *p_uuid = (bt_uuid_t*)property->val + i;
- memset(buf, 0, sizeof(buf));
- uuid_to_string(p_uuid, buf);
- strcat(value, buf);
- strcat(value, ";");
- }
- value[strlen(value)] = 0;
- }break;
- default:
- {
- return BT_STATUS_FAIL;
+ bt_uuid_t *p_uuid = (bt_uuid_t*)prop->val;
+ uint32_t num_uuids = 0;
+ btif_in_split_uuids_string_to_list(value, p_uuid, &num_uuids);
+ prop->len = num_uuids * sizeof(bt_uuid_t);
+ ret = TRUE;
}
- }
- return BT_STATUS_SUCCESS;
-}
-
-/*******************************************************************************
-**
-** Function btif_in_get_remote_device_path_from_property
-**
-** Description Internal helper function to map a property type
-** to the NVRAM filename key
-**
-** Returns NVRAM filename key if successfull, NULL otherwise
-**
-*******************************************************************************/
-static char* btif_in_get_remote_device_path_from_property(bt_property_type_t type)
-{
- switch (type)
- {
- case BT_PROPERTY_BDADDR:
- case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
- return BTIF_STORAGE_PATH_REMOTE_DEVICES;
- case BT_PROPERTY_BDNAME:
- return BTIF_STORAGE_PATH_REMOTE_NAMES;
- case BT_PROPERTY_CLASS_OF_DEVICE:
- return BTIF_STORAGE_PATH_REMOTE_DEVCLASSES;
- case BT_PROPERTY_TYPE_OF_DEVICE:
- return BTIF_STORAGE_PATH_REMOTE_DEVTYPES;
- case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
- return BTIF_STORAGE_PATH_REMOTE_ALIASES;
- case BT_PROPERTY_UUIDS:
- return BTIF_STORAGE_PATH_REMOTE_SERVICES;
+ break;
+ }
default:
- return NULL;
+ error("Unknow prop type:%d", prop->type);
+ return FALSE;
}
+ return ret;
}
-/*******************************************************************************
-**
-** Function btif_in_load_device_iter_cb
-**
-** Description Internal iterator callback from UNV when loading the
-** link-keys
-**
-** Returns
-**
-*******************************************************************************/
-
-int btif_in_load_device_iter_cb(char *key, char *value, void *userdata)
-{
- btif_bonded_devices_t *p_bonded_devices = (btif_bonded_devices_t *)userdata;
- DEV_CLASS dev_class = {0, 0, 0};
- bt_bdaddr_t bd_addr;
- LINK_KEY link_key;
- uint8_t key_type;
- uint8_t pin_length;
- int offset = 0;
- int8_t temp[3];
- uint32_t i;
-
- memset(temp, 0, sizeof(temp));
-
- BTIF_TRACE_DEBUG3("%s %s %s", __FUNCTION__, key, value);
-
- /* convert 32 char linkkey (fixed size) */
- for (i = 0; i < LINK_KEY_LEN; i++)
- {
- memcpy(temp, value + (i * 2), 2);
- link_key[i] = (uint8_t) strtol((const char *)temp, NULL, 16);
- offset+=2;
- }
-
- /* skip space */
- offset++;
-
- /* convert decimal keytype (max 2 ascii chars) */
- memset(temp, 0, sizeof(temp));
- memcpy(temp, value + offset, 2);
- key_type = (uint8_t)strtoul((const char *)temp, NULL, 10);
-
- /* value + space */
- offset+=2;
-
- /* convert decimal pinlen (max 2 ascii chars) */
- memset(temp, 0, sizeof(temp));
- memcpy(temp, value + offset, 2);
- pin_length = (uint8_t)strtoul((const char *)temp, NULL, 10);
-
- /* convert bd address (keystring) */
- str2bd(key, &bd_addr);
-
- /* add extracted information to BTA security manager */
- BTA_DmAddDevice(bd_addr.address, dev_class, link_key, 0, 0, key_type, 0);
-
- /* Fill in the bonded devices */
- memcpy(&p_bonded_devices->devices[p_bonded_devices->num_devices++], &bd_addr, sizeof(bt_bdaddr_t));
-
- return 0;
-}
-
-
-int btif_in_get_device_iter_cb(char *key, char *value, void *userdata)
-{
- btif_bonded_devices_t *p_bonded_devices = (btif_bonded_devices_t *)userdata;
- DEV_CLASS dev_class = {0, 0, 0};
- bt_bdaddr_t bd_addr;
- LINK_KEY link_key;
- uint8_t key_type;
- uint8_t pin_length;
- int offset = 0;
- int8_t temp[3];
- uint32_t i;
-
- memset(temp, 0, sizeof(temp));
-
- BTIF_TRACE_DEBUG3("%s %s %s", __FUNCTION__, key, value);
-
- /* convert 32 char linkkey (fixed size) */
- for (i = 0; i < LINK_KEY_LEN; i++)
- {
- memcpy(temp, value + (i * 2), 2);
- link_key[i] = (uint8_t) strtol((const char *)temp, NULL, 16);
- offset+=2;
- }
-
- /* skip space */
- offset++;
-
- /* convert decimal keytype (max 2 ascii chars) */
- memset(temp, 0, sizeof(temp));
- memcpy(temp, value + offset, 2);
- key_type = (uint8_t)strtoul((const char *)temp, NULL, 10);
-
- /* value + space */
- offset+=2;
-
- /* convert decimal pinlen (max 2 ascii chars) */
- memset(temp, 0, sizeof(temp));
- memcpy(temp, value + offset, 2);
- pin_length = (uint8_t)strtoul((const char *)temp, NULL, 10);
-
- /* convert bd address (keystring) */
- str2bd(key, &bd_addr);
-
-
- /* Fill in the bonded devices */
- memcpy(&p_bonded_devices->devices[p_bonded_devices->num_devices++], &bd_addr, sizeof(bt_bdaddr_t));
-
- return 0;
-}
/*******************************************************************************
**
@@ -612,43 +429,49 @@ int btif_in_get_device_iter_cb(char *key, char *value, void *userdata)
** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
**
*******************************************************************************/
-static bt_status_t btif_in_fetch_and_load_bonded_devices(btif_bonded_devices_t *p_bonded_devices)
-{
- char *fname;
- int ret;
-
- memset(p_bonded_devices, 0, sizeof(btif_bonded_devices_t));
-
- fname = btif_in_make_filename(NULL, BTIF_STORAGE_PATH_REMOTE_LINKKEYS);
-
- if (fname == NULL)
- return BT_STATUS_FAIL;
-
- ret = unv_read_key_iter(fname, btif_in_load_device_iter_cb, p_bonded_devices);
-
- if (ret < 0)
- return BT_STATUS_FAIL;
-
- return BT_STATUS_SUCCESS;
-}
-
-static bt_status_t btif_in_fetch_bonded_devices(btif_bonded_devices_t *p_bonded_devices)
+static bt_status_t btif_in_fetch_bonded_devices(btif_bonded_devices_t *p_bonded_devices, int add)
{
- char *fname;
- int ret;
-
+ debug("in add:%d", add);
memset(p_bonded_devices, 0, sizeof(btif_bonded_devices_t));
- fname = btif_in_make_filename(NULL, BTIF_STORAGE_PATH_REMOTE_LINKKEYS);
-
- if (fname == NULL)
- return BT_STATUS_FAIL;
-
- ret = unv_read_key_iter(fname, btif_in_get_device_iter_cb, p_bonded_devices);
-
- if (ret < 0)
- return BT_STATUS_FAIL;
-
+ char kname[128], vname[128];
+ short kpos;
+ int kname_size;
+ kname_size = sizeof(kname);
+ kname[0] = 0;
+ kpos = 0;
+ while((kpos = btif_config_next_key(kpos, "Remote", kname, &kname_size)) != -1)
+ {
+ debug("Remote device:%s, size:%d", kname, kname_size);
+ int type = BTIF_CFG_TYPE_BIN;
+ LINK_KEY link_key;
+ int size = sizeof(link_key);
+ if(btif_config_get("Remote", kname, "LinkKey", (char*)link_key, &size, &type))
+ {
+ int linkkey_type;
+ if(btif_config_get_int("Remote", kname, "LinkKeyType", &linkkey_type))
+ {
+ //int pin_len;
+ //btif_config_get_int("Remote", kname, "PinLength", &pin_len))
+ bt_bdaddr_t bd_addr;
+ str2bd(kname, &bd_addr);
+ if(add)
+ {
+ DEV_CLASS dev_class = {0, 0, 0};
+ int cod;
+ if(btif_config_get_int("Remote", kname, "DevClass", &cod))
+ uint2devclass((UINT32)cod, dev_class);
+ BTA_DmAddDevice(bd_addr.address, dev_class, link_key, 0, 0, (UINT8)linkkey_type, 0);
+ }
+ memcpy(&p_bonded_devices->devices[p_bonded_devices->num_devices++], &bd_addr, sizeof(bt_bdaddr_t));
+ }
+ else error("bounded device:%s, LinkKeyType or PinLength is invalid", kname);
+ }
+ else debug("Remote device:%s, no link key", kname);
+ kname_size = sizeof(kname);
+ kname[0] = 0;
+ }
+ debug("out");
return BT_STATUS_SUCCESS;
}
@@ -675,78 +498,6 @@ static int hex_str_to_int(const char* str, int size)
return n;
}
-/*******************************************************************************
-**
-** Function btif_in_load_hid_info_iter_cb
-**
-** Description Internal iterator callback from UNV when loading the
-** hid device info
-**
-** Returns
-**
-*******************************************************************************/
-
-int btif_in_load_hid_info_iter_cb(char *key, char *value, void *userdata)
-{
- btif_bonded_devices_t *p_bonded_devices = (btif_bonded_devices_t *)userdata;
- bt_bdaddr_t bd_addr;
- tBTA_HH_DEV_DSCP_INFO dscp_info;
- uint32_t i;
- uint16_t attr_mask,a;
- uint8_t sub_class;
- uint8_t app_id;
- BD_ADDR* bda;
- char *p;
-
-
- BTIF_TRACE_DEBUG3("%s - %s - %s", __FUNCTION__, key, value);
-
- p = value;
- attr_mask = (uint16_t) hex_str_to_int(p, 4);
- p +=5;
- sub_class = (uint8_t) hex_str_to_int(p, 2);
- p +=3;
- app_id = (uint8_t) hex_str_to_int(p, 2);
- p +=3;
- dscp_info.vendor_id = (uint16_t) hex_str_to_int(p, 4);
- p += 5;
- dscp_info.product_id = (uint16_t) hex_str_to_int(p, 4);
- p += 5;
- dscp_info.version = (uint8_t) hex_str_to_int(p, 4);
- p += 5;
- dscp_info.ctry_code = (uint8_t) hex_str_to_int(p, 2);
- p += 3;
- dscp_info.descriptor.dl_len = (uint16_t) hex_str_to_int(p, 4);
- p += 5;
-
- dscp_info.descriptor.dsc_list = (UINT8 *) GKI_getbuf(dscp_info.descriptor.dl_len);
- if (dscp_info.descriptor.dsc_list == NULL)
- {
- ALOGE("%s: Failed to allocate DSCP for CB", __FUNCTION__);
- return BT_STATUS_FAIL;
- }
- for (i = 0; i < dscp_info.descriptor.dl_len; i++)
- {
- dscp_info.descriptor.dsc_list[i] = (uint8_t) hex_str_to_int(p, 2);
- p += 2;
- }
-
- /* convert bd address (keystring) */
- str2bd(key, &bd_addr);
- bda = (BD_ADDR*) &bd_addr;
-
- // add extracted information to BTA HH
- if (btif_hh_add_added_dev(bd_addr,attr_mask))
- {
- BTIF_TRACE_DEBUG0("btif_in_load_hid_info_iter_cb: adding device");
- BTA_HhAddDev(bd_addr.address, attr_mask, sub_class,
- app_id, dscp_info);
- }
-
- GKI_freebuf(dscp_info.descriptor.dsc_list);
- return 0;
-}
-
/************************************************************************************
** Externs
************************************************************************************/
@@ -775,11 +526,6 @@ int btif_in_load_hid_info_iter_cb(char *key, char *value, void *userdata)
*******************************************************************************/
bt_status_t btif_storage_get_adapter_property(bt_property_t *property)
{
- bt_status_t status;
- char *fname;
- char *value;
- int ret;
- char linebuf[BTIF_STORAGE_MAX_LINE_SZ];
/* initialize property->len */
property->len = 0;
@@ -798,7 +544,7 @@ bt_status_t btif_storage_get_adapter_property(bt_property_t *property)
{
btif_bonded_devices_t bonded_devices;
- btif_in_fetch_bonded_devices(&bonded_devices);
+ btif_in_fetch_bonded_devices(&bonded_devices, 0);
BTIF_TRACE_DEBUG2("%s: Number of bonded devices: %d Property:BT_PROPERTY_ADAPTER_BONDED_DEVICES", __FUNCTION__, bonded_devices.num_devices);
@@ -851,39 +597,12 @@ bt_status_t btif_storage_get_adapter_property(bt_property_t *property)
}
/* fall through for other properties */
-
- /* create filepath */
- fname = btif_in_make_filename(NULL, BTIF_STORAGE_PATH_ADAPTER_INFO);
-
- if (fname == NULL)
- {
- return BT_STATUS_FAIL;
- }
-
- ret = unv_create_file(fname);
-
- if (ret < 0)
- {
- return BT_STATUS_FAIL;
- }
-
- value = unv_read_key( fname,
- btif_in_get_adapter_key_from_type(property->type),
- linebuf, UNV_MAXLINE_LENGTH);
-
- if (value == NULL)
+ if(!cfg2prop(NULL, property))
{
- /* properties not yet existing, request default values from bta */
return btif_dm_get_adapter_property(property);
}
- else
- {
- /* convert to property_t data structure */
- status = btif_in_str_to_property(value, property);
- }
-
- return status;
-}
+ return BT_STATUS_SUCCESS;
+ }
/*******************************************************************************
**
@@ -898,32 +617,7 @@ bt_status_t btif_storage_get_adapter_property(bt_property_t *property)
*******************************************************************************/
bt_status_t btif_storage_set_adapter_property(bt_property_t *property)
{
- char *fname;
- char value[1200];
- int ret;
-
- fname = btif_in_make_filename(NULL, BTIF_STORAGE_PATH_ADAPTER_INFO);
- if (fname == NULL)
- {
- return BT_STATUS_FAIL;
- }
- ret = unv_create_file(fname);
- if (ret < 0)
- {
- return BT_STATUS_FAIL;
- }
-
- if (btif_in_property_to_str(property, value) != BT_STATUS_SUCCESS)
- {
- return BT_STATUS_FAIL;
- }
- ret = unv_write_key(fname, btif_in_get_adapter_key_from_type(property->type), value);
- if (ret < 0)
- {
- return BT_STATUS_FAIL;
- }
-
- return BT_STATUS_SUCCESS;
+ return prop2cfg(NULL, property) ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
}
/*******************************************************************************
@@ -942,32 +636,8 @@ bt_status_t btif_storage_set_adapter_property(bt_property_t *property)
bt_status_t btif_storage_get_remote_device_property(bt_bdaddr_t *remote_bd_addr,
bt_property_t *property)
{
- char linebuf[BTIF_STORAGE_MAX_LINE_SZ];
- char *fname;
- char *value;
- int ret;
- bdstr_t bdstr;
-
- fname = btif_in_make_filename(NULL,
- btif_in_get_remote_device_path_from_property(property->type));
-
- if (fname == NULL)
- {
- return BT_STATUS_FAIL;
- }
-
-
- ret = unv_create_file(fname);
- if (ret < 0)
- {
- return BT_STATUS_FAIL;
- }
-
- value = unv_read_key(fname, bd2str(remote_bd_addr, &bdstr), linebuf, BTIF_STORAGE_MAX_LINE_SZ);
-
- return btif_in_str_to_property(value, property);
+ return cfg2prop(remote_bd_addr, property) ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
}
-
/*******************************************************************************
**
** Function btif_storage_set_remote_device_property
@@ -982,40 +652,7 @@ bt_status_t btif_storage_get_remote_device_property(bt_bdaddr_t *remote_bd_addr,
bt_status_t btif_storage_set_remote_device_property(bt_bdaddr_t *remote_bd_addr,
bt_property_t *property)
{
- char value[1200];
- char *fname;
- bdstr_t bdstr;
- int ret;
-
- fname = btif_in_make_filename(NULL,
- btif_in_get_remote_device_path_from_property(property->type));
-
-
- if (fname == NULL)
- {
- return BT_STATUS_FAIL;
- }
-
-
- ret = unv_create_file(fname);
- if (ret < 0)
- {
- return BT_STATUS_FAIL;
- }
- memset(value, 0, sizeof(value));
-
- if (btif_in_property_to_str(property, value) != BT_STATUS_SUCCESS)
- {
- return BT_STATUS_FAIL;
- }
-
- ret = unv_write_key(fname, bd2str(remote_bd_addr, &bdstr), value);
- if (ret < 0)
- {
- return BT_STATUS_FAIL;
- }
-
- return BT_STATUS_SUCCESS;
+ return prop2cfg(remote_bd_addr, property) ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
}
/*******************************************************************************
@@ -1078,48 +715,13 @@ bt_status_t btif_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr,
uint8_t key_type,
uint8_t pin_length)
{
- char value[STORAGE_REMOTE_LINKKEYS_ENTRY_SIZE];
- uint32_t i = 0;
- char *fname;
bdstr_t bdstr;
- int ret;
-
- fname = btif_in_make_filename(NULL,
- BTIF_STORAGE_PATH_REMOTE_LINKKEYS);
- if (fname == NULL)
- {
- return BT_STATUS_FAIL;
- }
- ret = unv_create_file(fname);
-
- if (ret < 0)
- {
- return BT_STATUS_FAIL;
- }
-
- /* check ascii representations doesn't exceed max size */
-
- if (key_type > STORAGE_KEY_TYPE_MAX)
- return BT_STATUS_FAIL;
-
- if (pin_length > PIN_CODE_LEN)
- return BT_STATUS_FAIL;
-
- memset(value, 0, sizeof(value));
-
- for (i = 0; i < LINK_KEY_LEN; i++)
- sprintf(value + (i * 2), "%2.2X", link_key[i]);
-
- sprintf(value + (LINK_KEY_LEN*2), " %d %d", key_type, pin_length);
-
- ret = unv_write_key(fname, bd2str(remote_bd_addr, &bdstr), value);
-
- if (ret < 0)
- {
- return BT_STATUS_FAIL;
- }
-
- return BT_STATUS_SUCCESS;
+ bd2str(remote_bd_addr, &bdstr);
+ int ret = btif_config_set_int("Remote", bdstr, "LinkKeyType", (int)key_type);
+ ret &= btif_config_set_int("Remote", bdstr, "PinLength", (int)pin_length);
+ ret &= btif_config_set("Remote", bdstr, "LinkKey", (const char*)link_key, sizeof(LINK_KEY), BTIF_CFG_TYPE_BIN);
+ btif_config_save();
+ return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
}
/*******************************************************************************
@@ -1134,31 +736,15 @@ bt_status_t btif_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr,
*******************************************************************************/
bt_status_t btif_storage_remove_bonded_device(bt_bdaddr_t *remote_bd_addr)
{
- char *fname;
- int ret;
bdstr_t bdstr;
+ bd2str(remote_bd_addr, &bdstr);
+ debug("in bd addr:%s", bdstr);
+ int ret = btif_config_remove("Remote", bdstr, "LinkKeyType");
+ ret &= btif_config_remove("Remote", bdstr, "PinLength");
+ ret &= btif_config_remove("Remote", bdstr, "LinkKey");
+ btif_config_save();
+ return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
- fname = btif_in_make_filename(NULL,
- BTIF_STORAGE_PATH_REMOTE_LINKKEYS);
- if (fname == NULL)
- {
- return BT_STATUS_FAIL;
- }
- ret = unv_create_file(fname);
-
- if (ret < 0)
- {
- return BT_STATUS_FAIL;
- }
-
- ret = unv_remove_key(fname, bd2str(remote_bd_addr, &bdstr));
-
- if (ret < 0)
- {
- return BT_STATUS_FAIL;
- }
-
- return BT_STATUS_SUCCESS;
}
/*******************************************************************************
@@ -1190,7 +776,7 @@ bt_status_t btif_storage_load_bonded_devices(void)
bt_uuid_t remote_uuids[BT_MAX_NUM_UUIDS];
uint32_t cod, devtype;
- btif_in_fetch_and_load_bonded_devices(&bonded_devices);
+ btif_in_fetch_bonded_devices(&bonded_devices, 1);
/* Now send the adapter_properties_cb with all adapter_properties */
{
@@ -1304,94 +890,17 @@ bt_status_t btif_storage_add_hid_device_info(bt_bdaddr_t *remote_bd_addr,
UINT16 product_id, UINT16 version,
UINT8 ctry_code, UINT16 dl_len, UINT8 *dsc_list)
{
- char *hid_info;
- uint32_t i = 0;
- char *fname;
bdstr_t bdstr;
- int ret;
-
- char* p;
- size_t size;
-
- fname = btif_in_make_filename(NULL,
- BTIF_STORAGE_PATH_REMOTE_HIDINFO);
- if (fname == NULL)
- {
- return BT_STATUS_FAIL;
- }
- ret = unv_create_file(fname);
-
- if (ret < 0)
- {
- return BT_STATUS_FAIL;
- }
- BTIF_TRACE_DEBUG1("%s",__FUNCTION__);
-
-/* value = <attr_mask> <space> > <sub_class> <space> <app_id> <space>
- <vendor_id> <space> > <product_id> <space> <version> <space>
- <ctry_code> <space> > <desc_len> <space> <desc_list> <space> */
- size = (STORAGE_BDADDR_STRING_SZ + 1 + STORAGE_HID_ATRR_MASK_SIZE + 1 +
- STORAGE_HID_SUB_CLASS_SIZE + 1 + STORAGE_HID_APP_ID_SIZE+ 1 +
- STORAGE_HID_VENDOR_ID_SIZE+ 1 + STORAGE_HID_PRODUCT_ID_SIZE+ 1 +
- STORAGE_HID_VERSION_SIZE+ 1 + STORAGE_HID_CTRY_CODE_SIZE+ 1 +
- STORAGE_HID_DESC_LEN_SIZE+ 1 + (dl_len *2)+1);
-
- hid_info = (char *) malloc(size);
- if (hid_info == NULL) {
- BTIF_TRACE_ERROR2("%s: Oops, failed to allocate %d byte buffer for HID info string",
- __FUNCTION__, size);
- return BT_STATUS_FAIL;
- }
-
- //Convert the entries to hex and copy it to hid_info
- sprintf(hid_info, "%04X %02X %02X %04X %04X %04X %02X %04X ",
- attr_mask,sub_class,app_id,vendor_id,product_id,version,ctry_code,dl_len);
-
- i = 0;
- p = &hid_info[strlen(hid_info)];
- while ((i + 16) <= dl_len) {
- sprintf(p, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
- dsc_list[i], dsc_list[i+1], dsc_list[i+2], dsc_list[i+3],
- dsc_list[i+4], dsc_list[i+5], dsc_list[i+6], dsc_list[i+7],
- dsc_list[i+8], dsc_list[i+9], dsc_list[i+10], dsc_list[i+11],
- dsc_list[i+12], dsc_list[i+13], dsc_list[i+14], dsc_list[i+15]);
- p += 32;
- i += 16;
- }
- if ((i + 8) <= dl_len) {
- sprintf(p, "%02X%02X%02X%02X%02X%02X%02X%02X",
- dsc_list[i], dsc_list[i+1], dsc_list[i+2], dsc_list[i+3],
- dsc_list[i+4], dsc_list[i+5], dsc_list[i+6], dsc_list[i+7]);
- p += 16;
- i += 8;
- }
- if ((i + 4) <= dl_len) {
- sprintf(p, "%02X%02X%02X%02X",
- dsc_list[i], dsc_list[i+1], dsc_list[i+2], dsc_list[i+3]);
- p += 8;
- i += 4;
- }
- if ((i + 3) == dl_len) {
- sprintf(p, "%02X%02X%02X", dsc_list[i], dsc_list[i+1], dsc_list[i+2]);
- p += 6;
- }
- else if ((i + 2) == dl_len) {
- sprintf(p, "%02X%02X", dsc_list[i], dsc_list[i+1]);
- p += 4;
- }
- else if ((i + 1) == dl_len) {
- sprintf(p, "%02X", dsc_list[i]);
- p += 2;
- }
- *p = '\0';
-
- ret = unv_write_key(fname, bd2str(remote_bd_addr, &bdstr), hid_info);
- free(hid_info);
- if (ret < 0)
- {
- return BT_STATUS_FAIL;
- }
-
+ bd2str(remote_bd_addr, &bdstr);
+ btif_config_set_int("Remote", bdstr, "HidAttrMask", attr_mask);
+ btif_config_set_int("Remote", bdstr, "HidSubClass", sub_class);
+ btif_config_set_int("Remote", bdstr, "HidAppId", app_id);
+ btif_config_set_int("Remote", bdstr, "HidVendorId", vendor_id);
+ btif_config_set_int("Remote", bdstr, "HidProductId", product_id);
+ btif_config_set_int("Remote", bdstr, "HidVersion", version);
+ btif_config_set_int("Remote", bdstr, "HidCountryCode", ctry_code);
+ if(dl_len > 0)
+ btif_config_set("Remote", bdstr, "HidDescriptor", (const char*)dsc_list, dl_len, BTIF_CFG_TYPE_BIN);
return BT_STATUS_SUCCESS;
}
@@ -1407,17 +916,65 @@ bt_status_t btif_storage_add_hid_device_info(bt_bdaddr_t *remote_bd_addr,
*******************************************************************************/
bt_status_t btif_storage_load_bonded_hid_info(void)
{
- char *fname;
- int ret;
- fname = btif_in_make_filename(NULL, BTIF_STORAGE_PATH_REMOTE_HIDINFO);
+ debug("in");
+ bt_bdaddr_t bd_addr;
+ tBTA_HH_DEV_DSCP_INFO dscp_info;
+ uint32_t i;
+ uint16_t attr_mask;
+ uint8_t sub_class;
+ uint8_t app_id;
+
+ char kname[128], vname[128];
+ short kpos;
+ int kname_size;
+ kname_size = sizeof(kname);
+ kname[0] = 0;
+ kpos = 0;
+ memset(&dscp_info, 0, sizeof(dscp_info));
+ while((kpos = btif_config_next_key(kpos, "Remote", kname, &kname_size)) != -1)
+ {
+ debug("Remote device:%s, size:%d", kname, kname_size);
+ int value;
+ if(btif_config_get_int("Remote", kname, "HidAttrMask", &value))
+ {
+ attr_mask = (uint16_t)value;
- if (fname == NULL)
- return BT_STATUS_FAIL;
+ btif_config_get_int("Remote", kname, "HidSubClass", &value);
+ sub_class = (uint8_t)value;
- ret = unv_read_key_iter(fname, btif_in_load_hid_info_iter_cb, NULL);
+ btif_config_get_int("Remote", kname, "HidAppId", &value);
+ app_id = (uint8_t)value;
- if (ret < 0)
- return BT_STATUS_FAIL;
+ btif_config_get_int("Remote", kname, "HidVendorId", &value);
+ dscp_info.vendor_id = (uint16_t) value;
+
+ btif_config_get_int("Remote", kname, "HidProductId", &value);
+ dscp_info.product_id = (uint16_t) value;
+
+ btif_config_get_int("Remote", kname, "HidVersion", &value);
+ dscp_info.version = (uint8_t) value;
+
+ btif_config_get_int("Remote", kname, "HidCountryCode", &value);
+ dscp_info.ctry_code = (uint8_t) value;
+
+ int len = 0;
+ int type;
+ btif_config_get("Remote", kname, "HidDescriptor", NULL, &len, &type);
+ if(len > 0)
+ {
+ dscp_info.descriptor.dl_len = (uint16_t)len;
+ dscp_info.descriptor.dsc_list = (uint8_t*)alloca(len);
+ btif_config_get("Remote", kname, "HidDescriptor", (char*)dscp_info.descriptor.dsc_list, &len, &type);
+ }
+ str2bd(kname, &bd_addr);
+ // add extracted information to BTA HH
+ if (btif_hh_add_added_dev(bd_addr,attr_mask))
+ {
+ BTA_HhAddDev(bd_addr.address, attr_mask, sub_class,
+ app_id, dscp_info);
+ }
+ }
+ }
return BT_STATUS_SUCCESS;
}
@@ -1437,27 +994,16 @@ bt_status_t btif_storage_remove_hid_info(bt_bdaddr_t *remote_bd_addr)
char *fname;
int ret;
bdstr_t bdstr;
-
- fname = btif_in_make_filename(NULL,
- BTIF_STORAGE_PATH_REMOTE_HIDINFO);
- if (fname == NULL)
- {
- return BT_STATUS_FAIL;
- }
- ret = unv_create_file(fname);
-
- if (ret < 0)
- {
- return BT_STATUS_FAIL;
- }
-
- ret = unv_remove_key(fname, bd2str(remote_bd_addr, &bdstr));
-
- if (ret < 0)
- {
- return BT_STATUS_FAIL;
- }
-
+ bd2str(remote_bd_addr, &bdstr);
+
+ btif_config_remove("Remote", bdstr, "HidAttrMask");
+ btif_config_remove("Remote", bdstr, "HidSubClass");
+ btif_config_remove("Remote", bdstr, "HidAppId");
+ btif_config_remove("Remote", bdstr, "HidVendorId");
+ btif_config_remove("Remote", bdstr, "HidProductId");
+ btif_config_remove("Remote", bdstr, "HidVersion");
+ btif_config_remove("Remote", bdstr, "HidCountryCode");
+ btif_config_remove("Remote", bdstr, "HidDescriptor");
return BT_STATUS_SUCCESS;
}
@@ -1721,26 +1267,15 @@ bt_status_t btif_storage_write_hl_mdl_data(UINT8 app_idx, char *value, int value
bt_status_t btif_storage_load_autopair_device_list()
{
- char *fname, *key_name, *key_value;
+ char *key_name, *key_value;
int ret , i=0;
char linebuf[BTIF_STORAGE_MAX_LINE_SZ];
char *line;
FILE *fp;
- /* check if the auto pair device list is already present in the NV memory */
- fname = btif_in_make_filename(NULL, BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST);
-
- if (fname == NULL)
- {
- return BT_STATUS_FAIL;
- }
-
- key_value = unv_read_key(fname,BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_ADDR,linebuf, BTIF_STORAGE_MAX_LINE_SZ);
-
- if (key_value == NULL)
+ if(!btif_config_exist("Local", BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST, NULL))
{
/* first time loading of auto pair blacklist configuration */
- ret = unv_create_file(fname);
if (ret < 0)
{
@@ -1782,7 +1317,7 @@ bt_status_t btif_storage_load_autopair_device_list()
(strcmp(key_name, BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLACKLIST_ADDR) == 0))
{
key_value = strtok(NULL, BTIF_AUTO_PAIR_CONF_KEY_VAL_DELIMETER);
- unv_write_key (fname, key_name, key_value);
+ btif_config_set_str("Local", BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST, key_name, key_value);
}
}
fclose(fp);
@@ -1802,54 +1337,45 @@ bt_status_t btif_storage_load_autopair_device_list()
*******************************************************************************/
BOOLEAN btif_storage_is_device_autopair_blacklisted(bt_bdaddr_t *remote_dev_addr)
{
- char *fname;
- char *value, *token;
+ char *token;
int ret;
bdstr_t bdstr;
char bd_addr_lap[9];
char *dev_name_str;
uint8_t i = 0;
- char linebuf[BTIF_STORAGE_MAX_LINE_SZ];
+ char value[BTIF_STORAGE_MAX_LINE_SZ];
+ int value_size = sizeof(value);
bd2str(remote_dev_addr, &bdstr);
/* create a string with Lower Address Part from BD Address */
- snprintf(bd_addr_lap, 9, "%s", (char*)bdstr);
-
- for ( i =0; i <strlen(bd_addr_lap) ;i++)
- {
- bd_addr_lap[i] = toupper(bd_addr_lap[i]);
- }
- /* create filepath */
- fname = btif_in_make_filename(NULL, BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST);
-
- /* check if this device address LAP is same as one of the auto pair blackliseted LAP */
- value = unv_read_key( fname,
- BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_ADDR,
- linebuf, BTIF_STORAGE_MAX_LINE_SZ);
- if (value != NULL)
+ snprintf(bd_addr_lap, 9, "%s", (char*)bdstr);
+
+ for ( i =0; i <strlen(bd_addr_lap) ;i++)
+ {
+ bd_addr_lap[i] = toupper(bd_addr_lap[i]);
+ }
+ if(btif_config_get_str("Local", BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST,
+ BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_ADDR, value, &value_size))
{
if (strstr(value,bd_addr_lap) != NULL)
- return TRUE;
+ return TRUE;
}
dev_name_str = BTM_SecReadDevName((remote_dev_addr->address));
if (dev_name_str != NULL)
{
- value = unv_read_key( fname,
- BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_EXACTNAME,
- linebuf, BTIF_STORAGE_MAX_LINE_SZ);
- if (value != NULL)
+ value_size = sizeof(value);
+ if(btif_config_get_str("Local", BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST,
+ BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_EXACTNAME, value, &value_size))
{
if (strstr(value,dev_name_str) != NULL)
return TRUE;
}
-
- value = unv_read_key( fname,
- BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_PARTIALNAME,
- linebuf, BTIF_STORAGE_MAX_LINE_SZ);
- if (value != NULL)
+ value_size = sizeof(value);
+ if(btif_config_get_str("Local", BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST,
+ BTIF_STORAGE_KEY_AUTOPAIR_BLACKLIST_PARTIALNAME, value, &value_size))
{
token = strtok(value, BTIF_AUTO_PAIR_CONF_VALUE_SEPARATOR);
while (token != NULL)
@@ -1861,16 +1387,13 @@ BOOLEAN btif_storage_is_device_autopair_blacklisted(bt_bdaddr_t *remote_dev_add
}
}
}
-
- value = unv_read_key( fname,
- BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLACKLIST_ADDR,
- linebuf, BTIF_STORAGE_MAX_LINE_SZ);
- if (value != NULL)
+ if(btif_config_get_str("Local", BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST,
+ BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLACKLIST_ADDR, value, &value_size))
{
if (strstr(value,bdstr) != NULL)
return TRUE;
}
- return FALSE;
+ return FALSE;
}
/*******************************************************************************
@@ -1885,8 +1408,6 @@ BOOLEAN btif_storage_is_device_autopair_blacklisted(bt_bdaddr_t *remote_dev_add
*******************************************************************************/
bt_status_t btif_storage_add_device_to_autopair_blacklist(bt_bdaddr_t *remote_dev_addr)
{
- char *fname;
- char *value;
int ret;
bdstr_t bdstr;
char linebuf[BTIF_STORAGE_MAX_LINE_SZ+20];
@@ -1894,22 +1415,12 @@ bt_status_t btif_storage_add_device_to_autopair_blacklist(bt_bdaddr_t *remote_de
bd2str(remote_dev_addr, &bdstr);
strncpy(input_value, (char*)bdstr, 20);
- strncat (input_value,BTIF_AUTO_PAIR_CONF_VALUE_SEPARATOR, 20);
-
- /* create filepath */
- fname = btif_in_make_filename(NULL, BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST);
-
- if (fname == NULL)
+ strncat(input_value,BTIF_AUTO_PAIR_CONF_VALUE_SEPARATOR, 20);
+ int line_size = sizeof(linebuf);
+ if(btif_config_get_str("Local", BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST,
+ BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLACKLIST_ADDR, linebuf, &line_size))
{
- return BT_STATUS_FAIL;
- }
-
- value = unv_read_key( fname,
- BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLACKLIST_ADDR,
- linebuf, BTIF_STORAGE_MAX_LINE_SZ);
- if (value != NULL)
- {
- /* Append this address to the dynamic List of BD address */
+ /* Append this address to the dynamic List of BD address */
strncat (linebuf, input_value, BTIF_STORAGE_MAX_LINE_SZ);
}
else
@@ -1918,9 +1429,10 @@ bt_status_t btif_storage_add_device_to_autopair_blacklist(bt_bdaddr_t *remote_de
}
/* Write back the key value */
- ret = unv_write_key (fname, BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLACKLIST_ADDR,( const char *)linebuf);
+ ret = btif_config_set_str("Local", BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST,
+ BTIF_STORAGE_KEY_AUTOPAIR_DYNAMIC_BLACKLIST_ADDR, linebuf);
- return (ret == 0 ? BT_STATUS_SUCCESS:BT_STATUS_FAIL);
+ return ret ? BT_STATUS_SUCCESS:BT_STATUS_FAIL;
}
/*******************************************************************************
@@ -1935,8 +1447,6 @@ bt_status_t btif_storage_add_device_to_autopair_blacklist(bt_bdaddr_t *remote_de
*******************************************************************************/
BOOLEAN btif_storage_is_fixed_pin_zeros_keyboard(bt_bdaddr_t *remote_dev_addr)
{
- char *fname;
- char *value;
int ret;
bdstr_t bdstr;
char bd_addr_lap[9];
@@ -1951,17 +1461,11 @@ BOOLEAN btif_storage_is_fixed_pin_zeros_keyboard(bt_bdaddr_t *remote_dev_addr)
{
bd_addr_lap[i] = toupper(bd_addr_lap[i]);
}
-
- /* create filepath */
- fname = btif_in_make_filename(NULL, BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST);
-
- value = unv_read_key( fname,
- BTIF_STORAGE_KEY_AUTOPAIR_FIXPIN_KBLIST,
- linebuf, BTIF_STORAGE_MAX_LINE_SZ);
-
- if (value != NULL)
+ int line_size = sizeof(linebuf);
+ if(btif_config_get_str("Local", BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST,
+ BTIF_STORAGE_KEY_AUTOPAIR_FIXPIN_KBLIST, linebuf, &line_size))
{
- if (strstr(bd_addr_lap, value) != NULL)
+ if (strstr(bd_addr_lap, linebuf) != NULL)
return TRUE;
}
return FALSE;
diff --git a/btif/src/btif_util.c b/btif/src/btif_util.c
index 9ed2cb8..07f1896 100644
--- a/btif/src/btif_util.c
+++ b/btif/src/btif_util.c
@@ -137,6 +137,12 @@ UINT32 devclass2uint(DEV_CLASS dev_class)
return cod;
}
+void uint2devclass(UINT32 cod, DEV_CLASS dev_class)
+{
+ dev_class[2] = (UINT8)cod;
+ dev_class[1] = (UINT8)(cod >> 8);
+ dev_class[0] = (UINT8)(cod >> 16);
+}
static const UINT8 sdp_base_uuid[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
diff --git a/main/Android.mk b/main/Android.mk
index 1f1d60c..2464c24 100755
--- a/main/Android.mk
+++ b/main/Android.mk
@@ -37,6 +37,8 @@ LOCAL_SRC_FILES += \
../btif/src/btif_sock_sdp.c \
../btif/src/btif_sock_util.c \
../btif/src/btif_pan.c \
+ ../btif/src/btif_config.c \
+ ../btif/src/btif_config_util.cpp \
../btif/src/btif_profile_queue.c
# callouts
@@ -88,6 +90,7 @@ LOCAL_C_INCLUDES+= . \
$(LOCAL_PATH)/../embdrv/sbc/encoder/include \
$(LOCAL_PATH)/../audio_a2dp_hw \
$(bdroid_C_INCLUDES) \
+ external/tinyxml2
LOCAL_CFLAGS += -DBUILDCFG $(bdroid_CFLAGS) -Werror -Wno-error=maybe-uninitialized -Wno-error=uninitialized
@@ -114,7 +117,7 @@ LOCAL_SHARED_LIBRARIES := \
libbt-hci
#LOCAL_WHOLE_STATIC_LIBRARIES := libbt-brcm_gki libbt-brcm_stack libbt-brcm_bta
-LOCAL_STATIC_LIBRARIES := libbt-brcm_gki libbt-brcm_bta libbt-brcm_stack
+LOCAL_STATIC_LIBRARIES := libbt-brcm_gki libbt-brcm_bta libbt-brcm_stack libtinyxml2
LOCAL_MODULE := bluetooth.default
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw