diff options
-rw-r--r-- | btif/include/btif_config.h | 95 | ||||
-rw-r--r-- | btif/include/btif_config_util.h | 80 | ||||
-rw-r--r-- | btif/include/btif_sock_thread.h | 4 | ||||
-rw-r--r-- | btif/include/btif_util.h | 1 | ||||
-rw-r--r-- | btif/src/btif_config.c | 843 | ||||
-rw-r--r-- | btif/src/btif_config_util.cpp | 702 | ||||
-rwxr-xr-x | btif/src/btif_core.c | 18 | ||||
-rwxr-xr-x | btif/src/btif_dm.c | 4 | ||||
-rw-r--r-- | btif/src/btif_pan.c | 2 | ||||
-rw-r--r-- | btif/src/btif_sock.c | 2 | ||||
-rw-r--r-- | btif/src/btif_sock_thread.c | 79 | ||||
-rwxr-xr-x | btif/src/btif_storage.c | 1154 | ||||
-rw-r--r-- | btif/src/btif_util.c | 6 | ||||
-rwxr-xr-x | main/Android.mk | 5 |
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 = §ion_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 = §ion_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 = §ion_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 = §ion_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 |