15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 2009-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/************************************************************************************
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Filename:      btif_config.c
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Description:   Stores the local BT adapter and remote device properties in
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *                 NVRAM storage, typically as xml file in the
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *                 mobile's filesystem
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ***********************************************************************************/
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdlib.h>
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <time.h>
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h>
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <ctype.h>
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdio.h>
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <fcntl.h>
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <errno.h>
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <unistd.h>
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <dirent.h>
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/types.h>
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/stat.h>
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/mman.h>
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdlib.h>
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <private/android_filesystem_config.h>
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
44689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project#define LOG_TAG "btif_config"
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <hardware/bluetooth.h>
4786f97eda524568f2d264186844450db5e56dac36Matthew Xie#include "data_types.h"
4886f97eda524568f2d264186844450db5e56dac36Matthew Xie#include "bd.h"
49689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project#include "btif_api.h"
505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_config.h"
515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_config_util.h"
525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_sock_thread.h"
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_sock_util.h"
545cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen#include "btif_util.h"
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project//#define UNIT_TEST
575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define CFG_PATH "/data/misc/bluedroid/"
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define CFG_FILE_NAME "bt_config"
595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define CFG_FILE_EXT ".xml"
605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define CFG_FILE_EXT_OLD ".old"
615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define CFG_FILE_EXT_NEW ".new"
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define CFG_GROW_SIZE (10*sizeof(cfg_node))
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define GET_CHILD_MAX_COUNT(node) (short)((int)(node)->bytes / sizeof(cfg_node))
647939ed0c9a50c769e9e648a2d7751e0894b485edzzy#define GET_CHILD_COUNT(p) (short)((int)(p)->used / sizeof(cfg_node))
657939ed0c9a50c769e9e648a2d7751e0894b485edzzy#define ADD_CHILD_COUNT(p, c) (p)->used += (short)((c)*sizeof(cfg_node))
667939ed0c9a50c769e9e648a2d7751e0894b485edzzy#define DEC_CHILD_COUNT(p, c) (p)->used -= (short)((c)*sizeof(cfg_node))
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define GET_NODE_COUNT(bytes) (bytes / sizeof(cfg_node))
687939ed0c9a50c769e9e648a2d7751e0894b485edzzy#define GET_NODE_BYTES(c) (c * sizeof(cfg_node))
695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define MAX_NODE_BYTES 32000
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define CFG_CMD_SAVE 1
715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#ifndef FALSE
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define TRUE 1
745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define FALSE 0
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef struct cfg_node_s
775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    const char* name;
795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    union
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        struct cfg_node_s* child;
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        char* value;
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    };
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    short bytes;
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    short type;
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    short used;
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    short flag;
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} cfg_node;
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic pthread_mutex_t slot_lock;
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int pth = -1; //poll thread handle
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic cfg_node root;
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int cached_change;
94335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chenstatic int save_cmds_queued;
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void cfg_cmd_callback(int cmd_fd, int type, int flags, uint32_t user_id);
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline short alloc_node(cfg_node* p, short grow);
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void free_node(cfg_node* p);
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline short find_inode(const cfg_node* p, const char* name);
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic cfg_node* find_node(const char* section, const char* key, const char* name);
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int remove_node(const char* section, const char* key, const char* name);
1017939ed0c9a50c769e9e648a2d7751e0894b485edzzystatic int remove_filter_node(const char* section, const char* filter[], int filter_count, int max_allowed);
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline cfg_node* find_free_node(cfg_node* p);
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int set_node(const char* section, const char* key, const char* name,
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        const char* value, short bytes, short type);
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int save_cfg();
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void load_cfg();
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic short find_next_node(const cfg_node* p, short start, char* name, int* bytes);
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#ifdef UNIT_TEST
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void cfg_test_load();
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void cfg_test_write();
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void cfg_test_read();
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
1137939ed0c9a50c769e9e648a2d7751e0894b485edzzy#define MY_LOG_LEVEL appl_trace_level
1147939ed0c9a50c769e9e648a2d7751e0894b485edzzy#define MY_LOG_LAYER TRACE_LAYER_NONE | TRACE_ORG_APPL
1157939ed0c9a50c769e9e648a2d7751e0894b485edzzy
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void dump_node(const char* title, const cfg_node* p)
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
118689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    if(p) {
1197939ed0c9a50c769e9e648a2d7751e0894b485edzzy        bdld("%s, p->name:%s, child/value:%p, bytes:%d",
120689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project                          title, p->name, p->child, p->bytes);
1217939ed0c9a50c769e9e648a2d7751e0894b485edzzy        bdld("p->used:%d, type:%x, p->flag:%d",
122689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project                          p->used, p->type, p->flag);
1237939ed0c9a50c769e9e648a2d7751e0894b485edzzy    } else bdld("%s is NULL", title);
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1257939ed0c9a50c769e9e648a2d7751e0894b485edzzy
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////////////////////////
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btif_config_init()
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    static int initialized;
1307939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdld("in initialized:%d", initialized);
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(!initialized)
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        initialized = 1;
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        struct stat st;
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(stat(CFG_PATH, &st) != 0)
1367939ed0c9a50c769e9e648a2d7751e0894b485edzzy            bdle("%s does not exist, need provision", CFG_PATH);
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        btsock_thread_init();
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        init_slot_lock(&slot_lock);
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        lock_slot(&slot_lock);
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        root.name = "Bluedroid";
1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        alloc_node(&root, CFG_GROW_SIZE);
1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        dump_node("root", &root);
1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        pth = btsock_thread_create(NULL, cfg_cmd_callback);
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        load_cfg();
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        unlock_slot(&slot_lock);
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        #ifdef UNIT_TEST
1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            cfg_test_write();
1487939ed0c9a50c769e9e648a2d7751e0894b485edzzy            //cfg_test_read();
1497939ed0c9a50c769e9e648a2d7751e0894b485edzzy            exit(0);
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        #endif
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return pth >= 0;
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btif_config_get_int(const char* section, const char* key, const char* name, int* value)
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int size = sizeof(*value);
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int type = BTIF_CFG_TYPE_INT;
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return btif_config_get(section, key, name, (char*)value, &size, &type);
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btif_config_set_int(const char* section, const char* key, const char* name, int value)
1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return btif_config_set(section, key, name, (char*)&value, sizeof(value), BTIF_CFG_TYPE_INT);
1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btif_config_get_str(const char* section, const char* key, const char* name, char* value, int* size)
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int type = BTIF_CFG_TYPE_STR;
1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(value)
1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        *value = 0;
1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return btif_config_get(section, key, name, value, size, &type);
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btif_config_set_str(const char* section, const char* key, const char* name, const char* value)
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   value = value ? value : "";
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   return btif_config_set(section, key, name, value, strlen(value) + 1, BTIF_CFG_TYPE_STR);
1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btif_config_exist(const char* section, const char* key, const char* name)
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int ret = FALSE;
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(section && *section && key && *key)
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        lock_slot(&slot_lock);
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ret = find_node(section, key, name) != NULL;
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        unlock_slot(&slot_lock);
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return ret;
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btif_config_get(const char* section, const char* key, const char* name, char* value, int* bytes, int* type)
1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int ret = FALSE;
1907939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdla(section && *section && key && *key && name && *name && bytes && type);
1917939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdld("section:%s, key:%s, name:%s, value:%p, bytes:%d, type:%d",
1927939ed0c9a50c769e9e648a2d7751e0894b485edzzy                section, key, name, value, *bytes, *type);
1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(section && *section && key && *key && name && *name && bytes && type)
1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        lock_slot(&slot_lock);
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        const cfg_node* node = find_node(section, key, name);
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        dump_node("found node", node);
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(node)
1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if(*type == node->type && value && *bytes >= node->used)
2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if(node->used > 0)
2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    memcpy(value, node->value, node->used);
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                ret = TRUE;
2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *type = node->type;
2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            *bytes = node->used;
2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if(ret != TRUE)
2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if(*type != node->type)
2117939ed0c9a50c769e9e648a2d7751e0894b485edzzy                    bdle("value:%s, wrong type:%d, need to be type: %d",
212689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project                                      name, *type, node->type);
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if(value && *bytes < node->used)
2147939ed0c9a50c769e9e648a2d7751e0894b485edzzy                    bdle("value:%s, not enough size: %d bytes, need %d bytes",
215689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project                                      name, node->used, *bytes);
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        unlock_slot(&slot_lock);
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return ret;
2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btif_config_set(const char* section, const char* key, const char* name, const char*  value, int bytes, int type)
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int ret = FALSE;
2257939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdla(section && *section && key && *key && name && *name);
2267939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdla(bytes < MAX_NODE_BYTES);
2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(section && *section && key && *key && name && *name && bytes < MAX_NODE_BYTES)
2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        lock_slot(&slot_lock);
2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ret = set_node(section, key, name, value, (short)bytes, (short)type);
2317939ed0c9a50c769e9e648a2d7751e0894b485edzzy        if(ret && !(type & BTIF_CFG_TYPE_VOLATILE))
2327939ed0c9a50c769e9e648a2d7751e0894b485edzzy            cached_change++;
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        unlock_slot(&slot_lock);
2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return ret;
2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btif_config_remove(const char* section, const char* key, const char* name)
2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2397939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdla(section && *section && key && *key);
2407939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdld("section:%s, key:%s, name:%s", section, key, name);
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int ret = FALSE;
2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(section && *section && key && *key)
2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         lock_slot(&slot_lock);
2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         ret = remove_node(section, key, name);
2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         if(ret)
2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            cached_change++;
2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project         unlock_slot(&slot_lock);
2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return ret;
2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2527939ed0c9a50c769e9e648a2d7751e0894b485edzzy
2537939ed0c9a50c769e9e648a2d7751e0894b485edzzyint btif_config_filter_remove(const char* section, const char* filter[], int filter_count, int max_allowed)
2547939ed0c9a50c769e9e648a2d7751e0894b485edzzy{
2557939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdla(section && *section && max_allowed > 0);
2567939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdld("section:%s, filter:%s, filter count:%d, max allowed:%d",
2577939ed0c9a50c769e9e648a2d7751e0894b485edzzy                section, filter[0], filter_count, max_allowed);
2587939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int ret = FALSE;
2597939ed0c9a50c769e9e648a2d7751e0894b485edzzy    if(section && *section && max_allowed > 0)
2607939ed0c9a50c769e9e648a2d7751e0894b485edzzy    {
2617939ed0c9a50c769e9e648a2d7751e0894b485edzzy         lock_slot(&slot_lock);
2627939ed0c9a50c769e9e648a2d7751e0894b485edzzy         ret = remove_filter_node(section, filter, filter_count, max_allowed);
2637939ed0c9a50c769e9e648a2d7751e0894b485edzzy         if(ret)
2647939ed0c9a50c769e9e648a2d7751e0894b485edzzy            cached_change++;
2657939ed0c9a50c769e9e648a2d7751e0894b485edzzy         unlock_slot(&slot_lock);
2667939ed0c9a50c769e9e648a2d7751e0894b485edzzy    }
2677939ed0c9a50c769e9e648a2d7751e0894b485edzzy    return ret;
2687939ed0c9a50c769e9e648a2d7751e0894b485edzzy}
2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef struct {
2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    short si;
2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    short ki;
2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    short vi;
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    short reserved;
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} cfg_node_pos;
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectshort btif_config_next_key(short pos, const char* section, char * name, int* bytes)
2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int next = -1;
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    short si = find_inode(&root, section);
2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(si >= 0)
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        const cfg_node* section_node = &root.child[si];
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        next = find_next_node(section_node, pos, name, bytes);
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return next;
2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectshort btif_config_next_value(short pos, const char* section, const char* key, char* name, int* bytes)
2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int next = -1;
2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    short si = find_inode(&root, section);
2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(si >= 0)
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        const cfg_node* section_node = &root.child[si];
2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        short ki = find_inode(section_node, key);
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(ki >= 0)
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            const cfg_node* key_node = &section_node->child[ki];
3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            next = find_next_node(key_node, pos, name, bytes);
3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return next;
3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btif_config_enum(btif_config_enum_callback cb, void* user_data)
3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3087939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdla(cb);
3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(!cb)
3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return FALSE;
3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int si, ki, vi;
3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    cfg_node *section_node, *key_node, *value_node;
3147939ed0c9a50c769e9e648a2d7751e0894b485edzzy    for(si = 0; si < GET_CHILD_COUNT(&root); si++)
3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        section_node = &root.child[si];
3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(section_node->name && *section_node->name)
3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
3197939ed0c9a50c769e9e648a2d7751e0894b485edzzy            for(ki = 0; ki < GET_CHILD_COUNT(section_node); ki++)
3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                key_node = &section_node->child[ki];
3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if(key_node->name && *key_node->name)
3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
3247939ed0c9a50c769e9e648a2d7751e0894b485edzzy                    for(vi = 0; vi < GET_CHILD_COUNT(key_node); vi++)
3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        value_node = &key_node->child[vi];
3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        if(value_node->name && *value_node->name)
3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        {
3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                            cb(user_data, section_node->name, key_node->name, value_node->name,
3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                            value_node->value, value_node->used, value_node->type);
3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        }
3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return TRUE;
3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btif_config_save()
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
342335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen    int post_cmd = 0;
3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
344335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen    bdld("save_cmds_queued:%d, cached_change:%d", save_cmds_queued, cached_change);
345335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen    if((save_cmds_queued == 0) && (cached_change > 0))
346335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen    {
347335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen        post_cmd = 1;
348335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen        save_cmds_queued++;
349335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen        bdld("post_cmd set to 1, save_cmds_queued:%d", save_cmds_queued);
350335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen    }
3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
352335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen    /* don't hold lock when invoking send or else a deadlock could
353335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen     * occur when the socket thread tries to do the actual saving.
354335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen     */
355335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen    if (post_cmd)
356335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen        btsock_thread_post_cmd(pth, CFG_CMD_SAVE, NULL, 0, 0);
357335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return TRUE;
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid btif_config_flush()
3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    lock_slot(&slot_lock);
3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(cached_change > 0)
3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        save_cfg();
3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    unlock_slot(&slot_lock);
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
36786f97eda524568f2d264186844450db5e56dac36Matthew Xie
36886f97eda524568f2d264186844450db5e56dac36Matthew Xie/*******************************************************************************
36986f97eda524568f2d264186844450db5e56dac36Matthew Xie * Device information
37086f97eda524568f2d264186844450db5e56dac36Matthew Xie *******************************************************************************/
37186f97eda524568f2d264186844450db5e56dac36Matthew XieBOOLEAN btif_get_device_type(const BD_ADDR bd_addr, int *p_device_type)
37286f97eda524568f2d264186844450db5e56dac36Matthew Xie{
37386f97eda524568f2d264186844450db5e56dac36Matthew Xie    if (p_device_type == NULL)
37486f97eda524568f2d264186844450db5e56dac36Matthew Xie        return FALSE;
37586f97eda524568f2d264186844450db5e56dac36Matthew Xie
37686f97eda524568f2d264186844450db5e56dac36Matthew Xie    bt_bdaddr_t bda;
37786f97eda524568f2d264186844450db5e56dac36Matthew Xie    bdcpy(bda.address, bd_addr);
37886f97eda524568f2d264186844450db5e56dac36Matthew Xie
37986f97eda524568f2d264186844450db5e56dac36Matthew Xie    char bd_addr_str[18] = {0};
38086f97eda524568f2d264186844450db5e56dac36Matthew Xie    bd2str(&bda, &bd_addr_str);
38186f97eda524568f2d264186844450db5e56dac36Matthew Xie
38286f97eda524568f2d264186844450db5e56dac36Matthew Xie    if (!btif_config_get_int("Remote", bd_addr_str, "DevType", p_device_type))
38386f97eda524568f2d264186844450db5e56dac36Matthew Xie        return FALSE;
38486f97eda524568f2d264186844450db5e56dac36Matthew Xie
38586f97eda524568f2d264186844450db5e56dac36Matthew Xie    ALOGD("%s: Device [%s] type %d", __FUNCTION__, bd_addr_str, *p_device_type);
38686f97eda524568f2d264186844450db5e56dac36Matthew Xie    return TRUE;
38786f97eda524568f2d264186844450db5e56dac36Matthew Xie}
38886f97eda524568f2d264186844450db5e56dac36Matthew Xie
38986f97eda524568f2d264186844450db5e56dac36Matthew XieBOOLEAN btif_get_address_type(const BD_ADDR bd_addr, int *p_addr_type)
39086f97eda524568f2d264186844450db5e56dac36Matthew Xie{
39186f97eda524568f2d264186844450db5e56dac36Matthew Xie    if (p_addr_type == NULL)
39286f97eda524568f2d264186844450db5e56dac36Matthew Xie        return FALSE;
39386f97eda524568f2d264186844450db5e56dac36Matthew Xie
39486f97eda524568f2d264186844450db5e56dac36Matthew Xie    bt_bdaddr_t bda;
39586f97eda524568f2d264186844450db5e56dac36Matthew Xie    bdcpy(bda.address, bd_addr);
39686f97eda524568f2d264186844450db5e56dac36Matthew Xie
39786f97eda524568f2d264186844450db5e56dac36Matthew Xie    char bd_addr_str[18] = {0};
39886f97eda524568f2d264186844450db5e56dac36Matthew Xie    bd2str(&bda, &bd_addr_str);
39986f97eda524568f2d264186844450db5e56dac36Matthew Xie
40086f97eda524568f2d264186844450db5e56dac36Matthew Xie    if (!btif_config_get_int("Remote", bd_addr_str, "AddrType", p_addr_type))
40186f97eda524568f2d264186844450db5e56dac36Matthew Xie        return FALSE;
40286f97eda524568f2d264186844450db5e56dac36Matthew Xie
40386f97eda524568f2d264186844450db5e56dac36Matthew Xie    ALOGD("%s: Device [%s] address type %d", __FUNCTION__, bd_addr_str, *p_addr_type);
40486f97eda524568f2d264186844450db5e56dac36Matthew Xie    return TRUE;
40586f97eda524568f2d264186844450db5e56dac36Matthew Xie}
40686f97eda524568f2d264186844450db5e56dac36Matthew Xie
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/////////////////////////////////////////////////////////////////////////////////////////////
4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline short alloc_node(cfg_node* p, short grow)
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int new_bytes = p->bytes + grow;
4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(grow > 0 && new_bytes < MAX_NODE_BYTES)
4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        char* value = (char*)realloc(p->value, new_bytes);
4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(value)
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            short old_bytes = p->bytes;
4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            //clear to zero
4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memset(value + old_bytes, 0, grow);
4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p->bytes = old_bytes + grow;
4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p->value = value;
4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return old_bytes;//return the previous size
4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4237939ed0c9a50c769e9e648a2d7751e0894b485edzzy        else bdle("realloc failed, old_bytes:%d, grow:%d, total:%d", p->bytes, grow,  p->bytes + grow);
4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return -1;
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void free_node(cfg_node* p)
4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(p)
4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(p->child)
4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            free(p->child);
4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p->child = NULL;
4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(p->name)
4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            free((void*)p->name);
4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p->name = 0;
4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        p->used = p->bytes = p->flag = p->type = 0;
4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline short find_inode(const cfg_node* p, const char* name)
4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(p && p->child && name && *name)
4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        int i;
4497939ed0c9a50c769e9e648a2d7751e0894b485edzzy        int count = GET_CHILD_COUNT(p);
4507939ed0c9a50c769e9e648a2d7751e0894b485edzzy        //bdld("parent name:%s, child name:%s, child count:%d", p->name, name, count);
4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        for(i = 0; i < count; i++)
4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if(p->child[i].name && *p->child[i].name &&
4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                strcmp(p->child[i].name, name) == 0)
4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                  return (short)i;
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return -1;
4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline cfg_node* find_free_node(cfg_node* p)
4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(p && p->child)
4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4667939ed0c9a50c769e9e648a2d7751e0894b485edzzy        int count = GET_CHILD_COUNT(p);
4677939ed0c9a50c769e9e648a2d7751e0894b485edzzy        if(count < GET_CHILD_MAX_COUNT(p))
4687939ed0c9a50c769e9e648a2d7751e0894b485edzzy            return  p->child + count;
4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return NULL;
4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic cfg_node* find_add_node(cfg_node* p, const char* name)
4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int i = -1;
4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    cfg_node* node = NULL;
4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if((i = find_inode(p, name)) < 0)
4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(!(node = find_free_node(p)))
4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            int old_size = alloc_node(p, CFG_GROW_SIZE);
4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if(old_size >= 0)
4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                i = GET_NODE_COUNT(old_size);
4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                node = &p->child[i];
4857939ed0c9a50c769e9e648a2d7751e0894b485edzzy                ADD_CHILD_COUNT(p, 1);
4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
4877939ed0c9a50c769e9e648a2d7751e0894b485edzzy        } else ADD_CHILD_COUNT(p, 1);
4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else node = &p->child[i];
490831423ea1879244e746f39d7696ad4a66681f306Hemant Gupta    if(node && (!node->name))
4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        node->name = strdup(name);
4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return node;
4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int set_node(const char* section, const char* key, const char* name,
4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    const char* value, short bytes, short type)
4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int si = -1, ki = -1, vi = -1;
4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    cfg_node* section_node = NULL;
4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if((section_node = find_add_node(&root, section)))
5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_node* key_node;
5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if((key_node = find_add_node(section_node, key)))
5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            cfg_node* value_node;
5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if((value_node = find_add_node(key_node, name)))
5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if(value_node->bytes < bytes)
5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if(value_node->value)
5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        free(value_node->value);
5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    value_node->value = (char*)malloc(bytes);
5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if(value_node->value)
5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        value_node->bytes = bytes;
5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    else
5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
5167939ed0c9a50c769e9e648a2d7751e0894b485edzzy                        bdle("not enough memory!");
5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        value_node->bytes = 0;
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        return FALSE;
5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if(value_node->value && value != NULL && bytes > 0)
5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    memcpy(value_node->value, value, bytes);
5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                value_node->type = type;
5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                value_node->used = bytes;
5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return TRUE;
5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return FALSE;
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic cfg_node* find_node(const char* section, const char* key, const char* name)
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int si = -1, ki = -1, vi = -1;
5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if((si = find_inode(&root, section)) >= 0)
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_node* section_node = &root.child[si];
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(key)
5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if((ki = find_inode(section_node, key)) >= 0)
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                cfg_node* key_node = &section_node->child[ki];
5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if(name)
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    if((vi = find_inode(key_node, name)) >= 0)
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    {
5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        return &key_node->child[vi];
5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    }
5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    return NULL;
5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return key_node;
5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return NULL;
5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return section_node;
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return NULL;
5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic short find_next_node(const cfg_node* p, short start, char* name, int* bytes)
5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
5607939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdla(0 <= start && start < GET_CHILD_COUNT(p));
5617939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdld("in, start:%d, child count:%d, max count:%d", start, GET_CHILD_COUNT(p), GET_CHILD_MAX_COUNT(p));
5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    short next = -1;
5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(name) *name = 0;
5647939ed0c9a50c769e9e648a2d7751e0894b485edzzy    if(0 <= start && start < GET_CHILD_COUNT(p))
5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        int i;
5677939ed0c9a50c769e9e648a2d7751e0894b485edzzy        for(i = start; i < GET_CHILD_COUNT(p); i++)
5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            cfg_node* child = &p->child[i];
5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if(child->name)
5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                int name_bytes = strlen(child->name) + 1;
5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                if(name && bytes && *bytes >= name_bytes)
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    memcpy(name, child->name, name_bytes);
5767939ed0c9a50c769e9e648a2d7751e0894b485edzzy                    if(i + 1 < GET_CHILD_COUNT(p))
5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                        next = (short)(i + 1);
5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    *bytes = name_bytes;
5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                else if(bytes)
5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                {
5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                    *bytes = name_bytes;
5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                }
5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                break;
5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return next;
5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5907939ed0c9a50c769e9e648a2d7751e0894b485edzzystatic void free_child(cfg_node* p, int ichild, int count)
5917939ed0c9a50c769e9e648a2d7751e0894b485edzzy{
5927939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int child_count = GET_CHILD_COUNT(p);
5937939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdla(p && ichild + count <= child_count && count > 0);
5947939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int icount = ichild + count;
5957939ed0c9a50c769e9e648a2d7751e0894b485edzzy    icount = icount <= child_count ? icount : child_count;
5967939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int i;
5977939ed0c9a50c769e9e648a2d7751e0894b485edzzy    for(i = ichild; i < icount; i++)
5987939ed0c9a50c769e9e648a2d7751e0894b485edzzy        free_node(p->child + i);
5997939ed0c9a50c769e9e648a2d7751e0894b485edzzy    if(i < child_count)
6007939ed0c9a50c769e9e648a2d7751e0894b485edzzy    {
6017939ed0c9a50c769e9e648a2d7751e0894b485edzzy        int mv_count = child_count - i;
6027939ed0c9a50c769e9e648a2d7751e0894b485edzzy        memmove(p->child + ichild, p->child + i, GET_NODE_BYTES(mv_count));
6037939ed0c9a50c769e9e648a2d7751e0894b485edzzy        //cleanup the buffer of already moved children
6047939ed0c9a50c769e9e648a2d7751e0894b485edzzy        memset(p->child + i, 0, GET_NODE_BYTES(mv_count));
6057939ed0c9a50c769e9e648a2d7751e0894b485edzzy    }
6067939ed0c9a50c769e9e648a2d7751e0894b485edzzy    DEC_CHILD_COUNT(p, i - ichild);
6077939ed0c9a50c769e9e648a2d7751e0894b485edzzy}
6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int remove_node(const char* section, const char* key, const char* name)
6095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    short  si = -1, ki = -1, vi = -1;
6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if((si = find_inode(&root, section)) >= 0)
6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cfg_node* section_node = &root.child[si];
6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if((ki = find_inode(section_node, key)) >= 0)
6155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            cfg_node* key_node = &section_node->child[ki];
6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if(name == NULL)
6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
6197939ed0c9a50c769e9e648a2d7751e0894b485edzzy                int count = GET_CHILD_COUNT(key_node);
6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                int i;
6217939ed0c9a50c769e9e648a2d7751e0894b485edzzy                free_child(key_node, 0, count);
6227939ed0c9a50c769e9e648a2d7751e0894b485edzzy                free_child(section_node, ki, 1);
6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return TRUE;
6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            else if((vi = find_inode(key_node, name)) >= 0)
6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            {
6277939ed0c9a50c769e9e648a2d7751e0894b485edzzy                free_child(key_node, vi, 1);
6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                return TRUE;
6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            }
6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return FALSE;
6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6347939ed0c9a50c769e9e648a2d7751e0894b485edzzystatic inline int find_first_empty(cfg_node*p, int start, int count)
6357939ed0c9a50c769e9e648a2d7751e0894b485edzzy{
6367939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int i;
6377939ed0c9a50c769e9e648a2d7751e0894b485edzzy    for(i = start; i < count; i++)
6387939ed0c9a50c769e9e648a2d7751e0894b485edzzy    {
6397939ed0c9a50c769e9e648a2d7751e0894b485edzzy        if(p->child[i].name == NULL)
6407939ed0c9a50c769e9e648a2d7751e0894b485edzzy            return i;
6417939ed0c9a50c769e9e648a2d7751e0894b485edzzy    }
6427939ed0c9a50c769e9e648a2d7751e0894b485edzzy    return -1;
6437939ed0c9a50c769e9e648a2d7751e0894b485edzzy}
6447939ed0c9a50c769e9e648a2d7751e0894b485edzzystatic inline int find_first_occupy(cfg_node*p, int start, int count)
6457939ed0c9a50c769e9e648a2d7751e0894b485edzzy{
6467939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int i;
6477939ed0c9a50c769e9e648a2d7751e0894b485edzzy    for(i = start; i < count; i++)
6487939ed0c9a50c769e9e648a2d7751e0894b485edzzy        if(p->child[i].name)
6497939ed0c9a50c769e9e648a2d7751e0894b485edzzy            return i;
6507939ed0c9a50c769e9e648a2d7751e0894b485edzzy    return -1;
6517939ed0c9a50c769e9e648a2d7751e0894b485edzzy}
6527939ed0c9a50c769e9e648a2d7751e0894b485edzzy
6537939ed0c9a50c769e9e648a2d7751e0894b485edzzystatic void pack_child(cfg_node* p)
6547939ed0c9a50c769e9e648a2d7751e0894b485edzzy{
6557939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int child_count = GET_CHILD_COUNT(p);
6567939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int occupy = 1;
6577939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int empty = 0;
6587939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int i;
6597939ed0c9a50c769e9e648a2d7751e0894b485edzzy    for(;;)
6607939ed0c9a50c769e9e648a2d7751e0894b485edzzy    {
6617939ed0c9a50c769e9e648a2d7751e0894b485edzzy        empty = find_first_empty(p, empty, child_count);
6627939ed0c9a50c769e9e648a2d7751e0894b485edzzy        if(empty >= 0)
6637939ed0c9a50c769e9e648a2d7751e0894b485edzzy        {
6647939ed0c9a50c769e9e648a2d7751e0894b485edzzy            if(occupy <= empty)
6657939ed0c9a50c769e9e648a2d7751e0894b485edzzy                occupy = empty + 1;
6667939ed0c9a50c769e9e648a2d7751e0894b485edzzy            occupy = find_first_occupy(p, occupy, child_count);
6677939ed0c9a50c769e9e648a2d7751e0894b485edzzy            bdla(occupy != 0);
6687939ed0c9a50c769e9e648a2d7751e0894b485edzzy            if(occupy > 0)
6697939ed0c9a50c769e9e648a2d7751e0894b485edzzy            {//move
6707939ed0c9a50c769e9e648a2d7751e0894b485edzzy                p->child[empty] = p->child[occupy];
6717939ed0c9a50c769e9e648a2d7751e0894b485edzzy                memset(&p->child[occupy], 0, sizeof(cfg_node));
6727939ed0c9a50c769e9e648a2d7751e0894b485edzzy                empty++;
6737939ed0c9a50c769e9e648a2d7751e0894b485edzzy                occupy++;
6747939ed0c9a50c769e9e648a2d7751e0894b485edzzy            }
6757939ed0c9a50c769e9e648a2d7751e0894b485edzzy            else break;
6767939ed0c9a50c769e9e648a2d7751e0894b485edzzy        }
6777939ed0c9a50c769e9e648a2d7751e0894b485edzzy        else break;
6787939ed0c9a50c769e9e648a2d7751e0894b485edzzy    }
6797939ed0c9a50c769e9e648a2d7751e0894b485edzzy}
6807939ed0c9a50c769e9e648a2d7751e0894b485edzzystatic inline int value_in_filter(cfg_node* key, const char* filter[], int filter_count)
6817939ed0c9a50c769e9e648a2d7751e0894b485edzzy{
6827939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int i, j;
6837939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int child_count = GET_CHILD_COUNT(key);
6847939ed0c9a50c769e9e648a2d7751e0894b485edzzy    for(i = 0; i < child_count; i++)
6857939ed0c9a50c769e9e648a2d7751e0894b485edzzy    {
6867939ed0c9a50c769e9e648a2d7751e0894b485edzzy        if(key->child[i].name && *key->child[i].name)
6877939ed0c9a50c769e9e648a2d7751e0894b485edzzy        {
6887939ed0c9a50c769e9e648a2d7751e0894b485edzzy            for(j = 0; j < filter_count; j++)
6897939ed0c9a50c769e9e648a2d7751e0894b485edzzy                if(strcmp(filter[j], key->child[i].name) == 0)
6907939ed0c9a50c769e9e648a2d7751e0894b485edzzy                    return TRUE;
6917939ed0c9a50c769e9e648a2d7751e0894b485edzzy        }
6927939ed0c9a50c769e9e648a2d7751e0894b485edzzy    }
6937939ed0c9a50c769e9e648a2d7751e0894b485edzzy    return FALSE;
6947939ed0c9a50c769e9e648a2d7751e0894b485edzzy}
6957939ed0c9a50c769e9e648a2d7751e0894b485edzzystatic int remove_filter_node(const char* section, const char* filter[], int filter_count, int max_allowed)
6967939ed0c9a50c769e9e648a2d7751e0894b485edzzy{
6977939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int  si = -1;
6987939ed0c9a50c769e9e648a2d7751e0894b485edzzy    if((si = find_inode(&root, section)) < 0)
6997939ed0c9a50c769e9e648a2d7751e0894b485edzzy    {
7007939ed0c9a50c769e9e648a2d7751e0894b485edzzy        bdle("cannot find section:%s", section);
7017939ed0c9a50c769e9e648a2d7751e0894b485edzzy        return FALSE;
7027939ed0c9a50c769e9e648a2d7751e0894b485edzzy    }
7037939ed0c9a50c769e9e648a2d7751e0894b485edzzy    cfg_node* s = &root.child[si];
7047939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int child_count = GET_CHILD_COUNT(s);
7057939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdld("section:%s, curr child count:%d, filter count:%d", section, child_count, filter_count);
7067939ed0c9a50c769e9e648a2d7751e0894b485edzzy    if(child_count < max_allowed)
7077939ed0c9a50c769e9e648a2d7751e0894b485edzzy        return FALSE;
7087939ed0c9a50c769e9e648a2d7751e0894b485edzzy    //remove until half of max allowance left
7097939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int total_rm = child_count - max_allowed / 2;
7107939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int rm_count = 0;
7117939ed0c9a50c769e9e648a2d7751e0894b485edzzy    int i;
7127939ed0c9a50c769e9e648a2d7751e0894b485edzzy    for(i = 0; i < child_count; i++)
7137939ed0c9a50c769e9e648a2d7751e0894b485edzzy    {
7147939ed0c9a50c769e9e648a2d7751e0894b485edzzy        if(!value_in_filter(&s->child[i], filter, filter_count))
7157939ed0c9a50c769e9e648a2d7751e0894b485edzzy        {
7167939ed0c9a50c769e9e648a2d7751e0894b485edzzy            free_child(&s->child[i], 0, GET_CHILD_COUNT(&s->child[i]));
7177939ed0c9a50c769e9e648a2d7751e0894b485edzzy            free_node(&s->child[i]);
7187939ed0c9a50c769e9e648a2d7751e0894b485edzzy            rm_count++;
7197939ed0c9a50c769e9e648a2d7751e0894b485edzzy            if(rm_count >= total_rm)
7207939ed0c9a50c769e9e648a2d7751e0894b485edzzy                break;
7217939ed0c9a50c769e9e648a2d7751e0894b485edzzy        }
7227939ed0c9a50c769e9e648a2d7751e0894b485edzzy    }
7237939ed0c9a50c769e9e648a2d7751e0894b485edzzy    if(rm_count)
7247939ed0c9a50c769e9e648a2d7751e0894b485edzzy    {
7257939ed0c9a50c769e9e648a2d7751e0894b485edzzy        pack_child(s);
7267939ed0c9a50c769e9e648a2d7751e0894b485edzzy        DEC_CHILD_COUNT(s, rm_count);
7277939ed0c9a50c769e9e648a2d7751e0894b485edzzy        return TRUE;
7287939ed0c9a50c769e9e648a2d7751e0894b485edzzy    }
7297939ed0c9a50c769e9e648a2d7751e0894b485edzzy    return FALSE;
7307939ed0c9a50c769e9e648a2d7751e0894b485edzzy}
7317939ed0c9a50c769e9e648a2d7751e0894b485edzzy
7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int save_cfg()
7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    const char* file_name = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT;
7355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    const char* file_name_new = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT_NEW;
7365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    const char* file_name_old = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT_OLD;
7375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int ret = FALSE;
7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(access(file_name_old,  F_OK) == 0)
7395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        unlink(file_name_old);
7405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(access(file_name_new, F_OK) == 0)
7415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        unlink(file_name_new);
7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project   if(btif_config_save_file(file_name_new))
7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        cached_change = 0;
7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        chown(file_name_new, -1, AID_NET_BT_STACK);
7465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        chmod(file_name_new, 0660);
7475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rename(file_name, file_name_old);
7485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        rename(file_name_new, file_name);
7495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ret = TRUE;
7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7517939ed0c9a50c769e9e648a2d7751e0894b485edzzy    else bdle("btif_config_save_file failed");
7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return ret;
7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int load_bluez_cfg()
7565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    char adapter_path[256];
7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(load_bluez_adapter_info(adapter_path, sizeof(adapter_path)))
7595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(load_bluez_linkkeys(adapter_path))
7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return TRUE;
7625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
7635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return FALSE;
7645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void remove_bluez_cfg()
7665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
7675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    rename(BLUEZ_PATH, BLUEZ_PATH_BAK);
7685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
769689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Projectstatic void clean_newline_char()
770689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project{
771689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    char kname[128], vname[128];
772689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    short kpos = 0;
773689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    int kname_size, vname_size;
774689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    vname[0] = 0;
775689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    vname_size = sizeof(vname);
7767939ed0c9a50c769e9e648a2d7751e0894b485edzzy    //bdld("removing newline at the end of the adapter and device name");
777689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    if(btif_config_get_str("Local", "Adapter", "Name", vname, &vname_size) &&
778689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        vname_size > 2)
779689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    {
780689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        if(vname[vname_size - 2] == '\n')
781689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        {
7827939ed0c9a50c769e9e648a2d7751e0894b485edzzy            bdld("remove newline at the end of the adapter name:%s", vname);
783689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            vname[vname_size - 2] = 0;
784689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            btif_config_set_str("Local", "Adapter", "Name", vname);
785689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        }
786689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    }
787689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    do
788689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    {
789689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        kname_size = sizeof(kname);
790689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        kname[0] = 0;
791689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        kpos = btif_config_next_key(kpos, "Remote", kname, &kname_size);
7927939ed0c9a50c769e9e648a2d7751e0894b485edzzy        //bdld("Remote device:%s, size:%d", kname, kname_size);
793689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        vname_size = sizeof(vname);
794689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        vname[0] = 0;
795689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        if(btif_config_get_str("Remote", kname, "Name", vname, &vname_size) &&
796689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            vname_size > 2)
797689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        {
7987939ed0c9a50c769e9e648a2d7751e0894b485edzzy            bdld("remote device name:%s", vname);
799689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            if(vname[vname_size - 2] == '\n')
800689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            {
8017939ed0c9a50c769e9e648a2d7751e0894b485edzzy                bdld("remove newline at the end of the device name:%s", vname);
802689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project                vname[vname_size - 2] = 0;
803689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project                btif_config_set_str("Remote", kname, "Name", vname);
804689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project            }
805689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        }
806689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project     } while(kpos != -1);
807689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project}
8085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void load_cfg()
8095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
8105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    const char* file_name = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT;
8115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    const char* file_name_new = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT_NEW;
8125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    const char* file_name_old = CFG_PATH CFG_FILE_NAME CFG_FILE_EXT_OLD;
8135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if(!btif_config_load_file(file_name))
8145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        unlink(file_name);
8165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if(!btif_config_load_file(file_name_old))
8175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
8185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            unlink(file_name_old);
8195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            if(load_bluez_cfg() && save_cfg())
8205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                remove_bluez_cfg();
8215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
8225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
823689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    int bluez_migration_done = 0;
824689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    btif_config_get_int("Local", "Adapter", "BluezMigrationDone", &bluez_migration_done);
825689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    if(!bluez_migration_done)
826689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    {
827689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        //clean the new line char at the end of the device name. Caused by bluez config import bug
828689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        clean_newline_char();
829689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        btif_config_set_int("Local", "Adapter", "BluezMigrationDone", 1);
830689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        btif_config_save();
831689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    }
8325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void cfg_cmd_callback(int cmd_fd, int type, int size, uint32_t user_id)
8345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
8355cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(cmd_fd);
8365cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(size);
8375cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(user_id);
8385cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
8395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    switch(type)
8405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case CFG_CMD_SAVE:
8427939ed0c9a50c769e9e648a2d7751e0894b485edzzy        {
843335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen            int i;
844335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen            int last_cached_change;
845335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen
846335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen            // grab lock while accessing cached_change.
847335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen            lock_slot(&slot_lock);
848335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen            bdla(save_cmds_queued > 0);
849335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen            save_cmds_queued--;
850335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen            last_cached_change = cached_change;
8517939ed0c9a50c769e9e648a2d7751e0894b485edzzy            //hold the file saving until no more change in last 3 seconds.
8527939ed0c9a50c769e9e648a2d7751e0894b485edzzy            bdld("wait until no more changes in short time, cached change:%d", cached_change);
853335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen            for(i = 0; i < 100; i ++) //5 minutes max waiting
8547939ed0c9a50c769e9e648a2d7751e0894b485edzzy            {
855335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen                // don't sleep if there is nothing to do
856335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen                if(cached_change == 0)
857335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen                    break;
858335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen                // release lock during sleep
859335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen                unlock_slot(&slot_lock);
8607939ed0c9a50c769e9e648a2d7751e0894b485edzzy                sleep(3);
861335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen                lock_slot(&slot_lock);
862335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen                if(last_cached_change == cached_change)
8637939ed0c9a50c769e9e648a2d7751e0894b485edzzy                    break;
8647939ed0c9a50c769e9e648a2d7751e0894b485edzzy                last_cached_change = cached_change;
8657939ed0c9a50c769e9e648a2d7751e0894b485edzzy            }
8667939ed0c9a50c769e9e648a2d7751e0894b485edzzy            bdld("writing the bt_config.xml now, cached change:%d", cached_change);
8677939ed0c9a50c769e9e648a2d7751e0894b485edzzy            if(cached_change > 0)
8687939ed0c9a50c769e9e648a2d7751e0894b485edzzy                save_cfg();
8695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            unlock_slot(&slot_lock);
8705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
8717939ed0c9a50c769e9e648a2d7751e0894b485edzzy        }
8725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
8735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#ifdef UNIT_TEST
8755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void cfg_test_load()
8765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
8775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    load_cfg();
8785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    char kname[128], vname[128];
8795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    short kpos, vpos;
8805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int kname_size, vname_size;
8817939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdld("list all remote devices values:");
8825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    kname_size = sizeof(kname);
8835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    kname[0] = 0;
8845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    kpos = 0;
8855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    do
8865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
8875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        kpos = btif_config_next_key(kpos, "Remote Devices", kname, &kname_size);
8887939ed0c9a50c769e9e648a2d7751e0894b485edzzy        bdld("Remote devices:%s, size:%d", kname, kname_size);
8895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        vpos = 0;
8905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        vname[0] = 0;
8915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        vname_size = sizeof(vname);
8925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        while((vpos = btif_config_next_value(vpos, "Remote Devices", kname, vname, &vname_size)) != -1)
8935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
8945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            char v[128] = {0};
8955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            int vtype = BTIF_CFG_TYPE_STR;
8965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            int vsize = sizeof(v);
8975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            int ret = btif_config_get("Remote Devices", kname, vname, v, &vsize, &vtype);
8987939ed0c9a50c769e9e648a2d7751e0894b485edzzy            bdld("btif_config_get return:%d, Remote devices:%s, value name:%s, value:%s, value size:%d, type:0x%x",
899689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project                              ret, kname, vname, v, vsize, vtype);
9005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            vname[0] = 0;
9025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            vname_size = sizeof(vname);
9035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
9045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        kname[0] = 0;
9055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        kname_size = sizeof(kname);
9065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    } while(kpos != -1);
9075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void cfg_test_write()
9095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
9105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int i;
9115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    char key[128];
9137939ed0c9a50c769e9e648a2d7751e0894b485edzzy    const char* section = "Remote";
9145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    char link_key[64];
9155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for(i = 0; i < (int)sizeof(link_key); i++)
9165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        link_key[i] = i;
9177939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdld("[start write testing");
9187939ed0c9a50c769e9e648a2d7751e0894b485edzzy    if(btif_config_exist("test", "test cfg", "write"))
9197939ed0c9a50c769e9e648a2d7751e0894b485edzzy        return;
9207939ed0c9a50c769e9e648a2d7751e0894b485edzzy    btif_config_set_int("test", "test cfg", "write", 1);
9217939ed0c9a50c769e9e648a2d7751e0894b485edzzy    for(i = 0; i < 50; i++)
9225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9237939ed0c9a50c769e9e648a2d7751e0894b485edzzy        if(i % 3 == 0)
9247939ed0c9a50c769e9e648a2d7751e0894b485edzzy            sprintf(key, "Remote paired %d", i);
9257939ed0c9a50c769e9e648a2d7751e0894b485edzzy        else sprintf(key, "Remote %d", i);
9265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        link_key[0] = i;
9275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        btif_config_set_str(section, key, "class", "smart phone");
9287939ed0c9a50c769e9e648a2d7751e0894b485edzzy        if(i % 3 == 0)
9297939ed0c9a50c769e9e648a2d7751e0894b485edzzy        {
9307939ed0c9a50c769e9e648a2d7751e0894b485edzzy            if(i % 6 == 0)
9317939ed0c9a50c769e9e648a2d7751e0894b485edzzy                btif_config_set(section, key, "LinkKey", link_key, sizeof(link_key), BTIF_CFG_TYPE_BIN);
9327939ed0c9a50c769e9e648a2d7751e0894b485edzzy            else btif_config_set(section, key, "LE_KEY_LCSRK", link_key, sizeof(link_key), BTIF_CFG_TYPE_BIN);
9337939ed0c9a50c769e9e648a2d7751e0894b485edzzy        }
9347939ed0c9a50c769e9e648a2d7751e0894b485edzzy        btif_config_set_int(section, key, "count", i);
9357939ed0c9a50c769e9e648a2d7751e0894b485edzzy        if(!btif_config_exist(section, key, "time stamp"))
9367939ed0c9a50c769e9e648a2d7751e0894b485edzzy            btif_config_set_int(section, key, "time stamp", time(NULL));
9375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9387939ed0c9a50c769e9e648a2d7751e0894b485edzzy    static const char* exclude_filter[] =
9397939ed0c9a50c769e9e648a2d7751e0894b485edzzy    {"LinkKey", "LE_KEY_PENC", "LE_KEY_PID", "LE_KEY_PCSRK", "LE_KEY_LENC", "LE_KEY_LCSRK"};
9407939ed0c9a50c769e9e648a2d7751e0894b485edzzy    const int max_allowed_remote_device = 40;
9417939ed0c9a50c769e9e648a2d7751e0894b485edzzy    btif_config_filter_remove("Remote", exclude_filter, sizeof(exclude_filter)/sizeof(char*),
9427939ed0c9a50c769e9e648a2d7751e0894b485edzzy            max_allowed_remote_device);
9437939ed0c9a50c769e9e648a2d7751e0894b485edzzy    bdld("]end write testing");
9447939ed0c9a50c769e9e648a2d7751e0894b485edzzy    btif_config_flush();
9455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void cfg_test_read()
9475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
948689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    //debug("in");
9495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    char class[128] = {0};
9505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    char link_key[128] = {0};
9515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int size, type;
9525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    char key[128];
9535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    const char* section;
9545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    int ret, i;
9555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for(i = 0; i < 100; i++)
9565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
9575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        sprintf(key, "00:22:5F:97:56:%02d", i);
9587939ed0c9a50c769e9e648a2d7751e0894b485edzzy        section = "Remote";
9595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        size = sizeof(class);
9605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ret = btif_config_get_str(section, key, "class", class, &size);
9617939ed0c9a50c769e9e648a2d7751e0894b485edzzy        bdld("btif_config_get_str return:%d, Remote devices:%s, class:%s", ret, key, class);
9625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        size = sizeof(link_key);
9645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        type = BTIF_CFG_TYPE_BIN;
9655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ret = btif_config_get(section, key, "link keys", link_key, &size, &type);
966689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        //debug("btif_config_get return:%d, Remote devices:%s, link key:%x, %x",
967689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        //            ret, key, *(int *)link_key, *((int *)link_key + 1));
9685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        int timeout;
9705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        ret = btif_config_get_int(section, key, "connect time out", &timeout);
971689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project        //debug("btif_config_get_int return:%d, Remote devices:%s, connect time out:%d", ret, key, timeout);
9725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
9735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
974689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    // debug("testing btif_config_remove");
9755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    size = sizeof(class);
9765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    type = BTIF_CFG_TYPE_STR;
9777939ed0c9a50c769e9e648a2d7751e0894b485edzzy    btif_config_set("Remote", "00:22:5F:97:56:04", "Class Delete", class, strlen(class) + 1, BTIF_CFG_TYPE_STR);
9785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9797939ed0c9a50c769e9e648a2d7751e0894b485edzzy    btif_config_get("Remote", "00:22:5F:97:56:04", "Class Delete", class, &size, &type);
980689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    // debug("Remote devices, 00:22:5F:97:56:04 Class Delete:%s", class);
9817939ed0c9a50c769e9e648a2d7751e0894b485edzzy    btif_config_remove("Remote", "00:22:5F:97:56:04", "Class Delete");
9825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    size = sizeof(class);
9845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    type = BTIF_CFG_TYPE_STR;
9857939ed0c9a50c769e9e648a2d7751e0894b485edzzy    ret = btif_config_get("Remote", "00:22:5F:97:56:04", "Class Delete", class, &size, &type);
986689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    // debug("after removed, btif_config_get ret:%d, Remote devices, 00:22:5F:97:56:04 Class Delete:%s", ret, class);
987689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project    // debug("out");
9885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
98986f97eda524568f2d264186844450db5e56dac36Matthew Xie
99086f97eda524568f2d264186844450db5e56dac36Matthew Xie
9915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
992