btif_config.cc revision e909ff50ffae0612fc0434cd2130469868b81ae4
15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
3b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati *  Copyright (C) 2014 Google, Inc.
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
1949120dc867c7818511b5afec461dfc97d17eef58Marie Janssen#define LOG_TAG "bt_btif_config"
2049120dc867c7818511b5afec461dfc97d17eef58Marie Janssen
2149a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen#include "btif_config.h"
2249a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen
23b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati#include <assert.h>
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <ctype.h>
25b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati#include <pthread.h>
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdio.h>
2772a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker#include <string>
28b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati#include <string.h>
29646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker#include <time.h>
30d30195cbf09735da593e186c4c99cce6232b072eArman Uguray#include <unistd.h>
31b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
32db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "bt_types.h"
3395b74f252f534ec757aab1fc08e086e02b2cfe8dSharvil Nanavati#include "btcore/include/bdaddr.h"
34db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "btcore/include/module.h"
357b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker#include "btif_api.h"
3632b3a8a408b23aa28324ad9f56654c98fe2ac914Srinu Jella#include "btif_common.h"
3732b3a8a408b23aa28324ad9f56654c98fe2ac914Srinu Jella#include "btif_config.h"
389a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh#include "btif_config_transcode.h"
395cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen#include "btif_util.h"
40db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "osi/include/alarm.h"
41db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "osi/include/allocator.h"
4247d68ee6229ccec3deeaaf694fa86438d97333a4Scott James Remnant#include "osi/include/compat.h"
430f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/config.h"
4444802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati#include "osi/include/log.h"
45db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "osi/include/osi.h"
46b4a42e7b9c277cfd71a575cbdb104013855b80cdBluetooth Build Test#include "osi/include/properties.h"
47bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panicker
48e909ff50ffae0612fc0434cd2130469868b81ae4Jacky Cheung#define BT_CONFIG_SOURCE_TAG_NUM 1010001
49e909ff50ffae0612fc0434cd2130469868b81ae4Jacky Cheung
50646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker#define INFO_SECTION "Info"
51646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker#define FILE_TIMESTAMP "TimeCreated"
5272a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker#define FILE_SOURCE "FileSource"
53646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker#define TIME_STRING_LENGTH sizeof("YYYY-MM-DD HH:MM:SS")
54646134e0a04459f649cb50aa9f3272054630c345Ajay Panickerstatic const char* TIME_STRING_FORMAT = "%Y-%m-%d %H:%M:%S";
55646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker
56f2d6434a6b7ad98e20c7a601d2a0950237514837Arman Uguray// TODO(armansito): Find a better way than searching by a hardcoded path.
57f2d6434a6b7ad98e20c7a601d2a0950237514837Arman Uguray#if defined(OS_GENERIC)
58f2d6434a6b7ad98e20c7a601d2a0950237514837Arman Uguraystatic const char *CONFIG_FILE_PATH = "bt_config.conf";
5979b294d7cb4b48a371dd6698d85e08771ed79eb1Ajay Panickerstatic const char *CONFIG_BACKUP_PATH = "bt_config.bak";
609a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanhstatic const char *CONFIG_LEGACY_FILE_PATH = "bt_config.xml";
61f2d6434a6b7ad98e20c7a601d2a0950237514837Arman Uguray#else  // !defined(OS_GENERIC)
62b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatistatic const char *CONFIG_FILE_PATH = "/data/misc/bluedroid/bt_config.conf";
6379b294d7cb4b48a371dd6698d85e08771ed79eb1Ajay Panickerstatic const char *CONFIG_BACKUP_PATH = "/data/misc/bluedroid/bt_config.bak";
649a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanhstatic const char *CONFIG_LEGACY_FILE_PATH = "/data/misc/bluedroid/bt_config.xml";
65f2d6434a6b7ad98e20c7a601d2a0950237514837Arman Uguray#endif  // defined(OS_GENERIC)
66b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatistatic const period_ms_t CONFIG_SETTLE_PERIOD_MS = 3000;
677939ed0c9a50c769e9e648a2d7751e0894b485edzzy
68d77f1999ecece56c1cbb333f4ddc26f0b5bac2c5Marie Janssenstatic void timer_config_save_cb(void *data);
69b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssenstatic void btif_config_write(uint16_t event, char *p_param);
70bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panickerstatic bool is_factory_reset(void);
71bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panickerstatic void delete_config_files(void);
72d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssenstatic void btif_config_remove_unpaired(config_t *config);
737b266be449e4f915c419199c2312eb31f70e63bcAjay Panickerstatic void btif_config_remove_restricted(config_t *config);
7472a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panickerstatic config_t *btif_config_open(const char* filename);
75335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen
76190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panickerstatic enum ConfigSource {
77190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker  NOT_LOADED,
78190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker  ORIGINAL,
79190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker  BACKUP,
809a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh  LEGACY,
81190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker  NEW_FILE,
82190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker  RESET
83190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker} btif_config_source = NOT_LOADED;
84190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker
85bcfdd0ab24357c5dd842540e6c0e8f34ba7aac11Marie Janssenstatic int btif_config_devices_loaded = -1;
86646134e0a04459f649cb50aa9f3272054630c345Ajay Panickerstatic char btif_config_time_created[TIME_STRING_LENGTH];
87190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker
88b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati// TODO(zachoverflow): Move these two functions out, because they are too specific for this file
89b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati// {grumpy-cat/no, monty-python/you-make-me-sad}
90b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatibool btif_get_device_type(const BD_ADDR bd_addr, int *p_device_type)
9186f97eda524568f2d264186844450db5e56dac36Matthew Xie{
9286f97eda524568f2d264186844450db5e56dac36Matthew Xie    if (p_device_type == NULL)
93b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen        return false;
9486f97eda524568f2d264186844450db5e56dac36Matthew Xie
9586f97eda524568f2d264186844450db5e56dac36Matthew Xie    bt_bdaddr_t bda;
9686f97eda524568f2d264186844450db5e56dac36Matthew Xie    bdcpy(bda.address, bd_addr);
9786f97eda524568f2d264186844450db5e56dac36Matthew Xie
988a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati    bdstr_t bd_addr_str;
998a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati    bdaddr_to_string(&bda, bd_addr_str, sizeof(bd_addr_str));
10086f97eda524568f2d264186844450db5e56dac36Matthew Xie
1019d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati    if (!btif_config_get_int(bd_addr_str, "DevType", p_device_type))
102b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen        return false;
10386f97eda524568f2d264186844450db5e56dac36Matthew Xie
104b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen    LOG_DEBUG(LOG_TAG, "%s: Device [%s] type %d", __func__, bd_addr_str, *p_device_type);
105b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen    return true;
10686f97eda524568f2d264186844450db5e56dac36Matthew Xie}
10786f97eda524568f2d264186844450db5e56dac36Matthew Xie
108b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatibool btif_get_address_type(const BD_ADDR bd_addr, int *p_addr_type)
10986f97eda524568f2d264186844450db5e56dac36Matthew Xie{
11086f97eda524568f2d264186844450db5e56dac36Matthew Xie    if (p_addr_type == NULL)
111b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen        return false;
11286f97eda524568f2d264186844450db5e56dac36Matthew Xie
11386f97eda524568f2d264186844450db5e56dac36Matthew Xie    bt_bdaddr_t bda;
11486f97eda524568f2d264186844450db5e56dac36Matthew Xie    bdcpy(bda.address, bd_addr);
11586f97eda524568f2d264186844450db5e56dac36Matthew Xie
1168a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati    bdstr_t bd_addr_str;
1178a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati    bdaddr_to_string(&bda, bd_addr_str, sizeof(bd_addr_str));
11886f97eda524568f2d264186844450db5e56dac36Matthew Xie
1199d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati    if (!btif_config_get_int(bd_addr_str, "AddrType", p_addr_type))
120b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen        return false;
12186f97eda524568f2d264186844450db5e56dac36Matthew Xie
122b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen    LOG_DEBUG(LOG_TAG, "%s: Device [%s] address type %d", __func__, bd_addr_str, *p_addr_type);
123b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssen    return true;
12486f97eda524568f2d264186844450db5e56dac36Matthew Xie}
12586f97eda524568f2d264186844450db5e56dac36Matthew Xie
126b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatistatic pthread_mutex_t lock;  // protects operations on |config|.
127b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatistatic config_t *config;
12878bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavovstatic alarm_t *config_timer;
129b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
1309b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson// Module lifecycle functions
1319b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson
1329b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnsonstatic future_t *init(void) {
133b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_init(&lock, NULL);
134646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker  pthread_mutex_lock(&lock);
135bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panicker
136bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panicker  if (is_factory_reset())
137bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panicker    delete_config_files();
138bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panicker
13972a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker  std::string file_source;
14072a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker
14172a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker  config = btif_config_open(CONFIG_FILE_PATH);
142190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker  btif_config_source = ORIGINAL;
143b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  if (!config) {
144b4a42e7b9c277cfd71a575cbdb104013855b80cdBluetooth Build Test    LOG_WARN(LOG_TAG, "%s unable to load config file: %s; using backup.",
1451eacb3d8933d5a4a394335cdfa9a99ee866a5990Ajay Panicker              __func__, CONFIG_FILE_PATH);
14672a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker    config = btif_config_open(CONFIG_BACKUP_PATH);
147190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker    btif_config_source = BACKUP;
14872a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker    file_source = "Backup";
1499a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh  }
1509a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh  if (!config) {
151b4a42e7b9c277cfd71a575cbdb104013855b80cdBluetooth Build Test    LOG_WARN(LOG_TAG, "%s unable to load backup; attempting to transcode legacy file.", __func__);
1529a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh    config = btif_config_transcode(CONFIG_LEGACY_FILE_PATH);
1539a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh    btif_config_source = LEGACY;
15472a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker    file_source = "Legacy";
1559a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh  }
1569a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh  if (!config) {
157b4a42e7b9c277cfd71a575cbdb104013855b80cdBluetooth Build Test    LOG_ERROR(LOG_TAG, "%s unable to transcode legacy file; creating empty config.", __func__);
1589a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh    config = config_new_empty();
1599a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh    btif_config_source = NEW_FILE;
16072a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker    file_source = "Empty";
1619a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh  }
162713993d1784ab7c23aee1fa3cf1ab8676cc0aa69Jakub Pawlowski
16372a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker  if (!file_source.empty())
16472a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker    config_set_string(config, INFO_SECTION, FILE_SOURCE, file_source.c_str());
165713993d1784ab7c23aee1fa3cf1ab8676cc0aa69Jakub Pawlowski
1669a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh  if (!config) {
167b4a42e7b9c277cfd71a575cbdb104013855b80cdBluetooth Build Test    LOG_ERROR(LOG_TAG, "%s unable to allocate a config object.", __func__);
1689a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh    goto error;
169b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  }
170b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
171d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen  btif_config_remove_unpaired(config);
172d77f1999ecece56c1cbb333f4ddc26f0b5bac2c5Marie Janssen
1737b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker  // Cleanup temporary pairings if we have left guest mode
1747b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker  if (!is_restricted_mode())
1757b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker    btif_config_remove_restricted(config);
1767b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker
177646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker  // Read or set config file creation timestamp
17872a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker  const char* time_str;
179713993d1784ab7c23aee1fa3cf1ab8676cc0aa69Jakub Pawlowski  time_str = config_get_string(config, INFO_SECTION, FILE_TIMESTAMP, NULL);
180646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker  if (time_str != NULL) {
181646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker    strlcpy(btif_config_time_created, time_str, TIME_STRING_LENGTH);
182646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker  } else {
183646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker    time_t current_time = time(NULL);
184646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker    struct tm* time_created = localtime(&current_time);
185646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker    strftime(btif_config_time_created, TIME_STRING_LENGTH, TIME_STRING_FORMAT, time_created);
186646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker    config_set_string(config, INFO_SECTION, FILE_TIMESTAMP, btif_config_time_created);
187646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker  }
188646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker
189b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  // TODO(sharvil): use a non-wake alarm for this once we have
1909b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson  // API support for it. There's no need to wake the system to
191b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  // write back to disk.
19278bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov  config_timer = alarm_new("btif.config");
19378bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov  if (!config_timer) {
194db554581079863974af8e1289646f5deea6fc044Marie Janssen    LOG_ERROR(LOG_TAG, "%s unable to create alarm.", __func__);
195b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati    goto error;
196b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  }
197b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
198e909ff50ffae0612fc0434cd2130469868b81ae4Jacky Cheung  LOG_EVENT_INT(BT_CONFIG_SOURCE_TAG_NUM, btif_config_source);
199e909ff50ffae0612fc0434cd2130469868b81ae4Jacky Cheung
200646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker  pthread_mutex_unlock(&lock);
2019b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson  return future_new_immediate(FUTURE_SUCCESS);
202b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
20378bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavoverror:
20478bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov  alarm_free(config_timer);
205b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  config_free(config);
206646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker  pthread_mutex_unlock(&lock);
207b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_destroy(&lock);
20878bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov  config_timer = NULL;
209b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  config = NULL;
2109a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh  btif_config_source = NOT_LOADED;
2119b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson  return future_new_immediate(FUTURE_FAIL);
2129b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson}
2139b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson
21472a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panickerstatic config_t *btif_config_open(const char *filename) {
21572a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker  config_t *config = config_new(filename);
21672a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker  if (!config)
21772a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker    return NULL;
21872a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker
21972a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker  if (!config_has_section(config, "Adapter")) {
22072a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker    LOG_ERROR(LOG_TAG, "Config is missing adapter section");
22172a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker    config_free(config);
22272a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker    return NULL;
22372a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker  }
22472a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker
22572a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker  return config;
22672a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker}
22772a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker
2289b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnsonstatic future_t *shut_down(void) {
2299b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson  btif_config_flush();
2309b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson  return future_new_immediate(FUTURE_SUCCESS);
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
232b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
2339b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnsonstatic future_t *clean_up(void) {
234b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  btif_config_flush();
235b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
23678bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov  alarm_free(config_timer);
237b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  config_free(config);
238b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_destroy(&lock);
23978bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov  config_timer = NULL;
240b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  config = NULL;
2419b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson  return future_new_immediate(FUTURE_SUCCESS);
2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
243b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
244713993d1784ab7c23aee1fa3cf1ab8676cc0aa69Jakub PawlowskiEXPORT_SYMBOL module_t btif_config_module = {
2459b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson  .name = BTIF_CONFIG_MODULE,
2469b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson  .init = init,
2479b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson  .start_up = NULL,
2489b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson  .shut_down = shut_down,
249713993d1784ab7c23aee1fa3cf1ab8676cc0aa69Jakub Pawlowski  .clean_up = clean_up
2509b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson};
2519b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson
2529d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatibool btif_config_has_section(const char *section) {
253b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
2549d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  assert(section != NULL);
255b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
256b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_lock(&lock);
2579d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  bool ret = config_has_section(config, section);
258b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_unlock(&lock);
259b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
260b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  return ret;
2617939ed0c9a50c769e9e648a2d7751e0894b485edzzy}
262b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
2639d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatibool btif_config_exist(const char *section, const char *key) {
264b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
2659d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  assert(section != NULL);
266b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(key != NULL);
267b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
268b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_lock(&lock);
2699d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  bool ret = config_has_key(config, section, key);
270b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_unlock(&lock);
271b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
272b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  return ret;
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
274b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
2759d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatibool btif_config_get_int(const char *section, const char *key, int *value) {
276b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
2779d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  assert(section != NULL);
278b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(key != NULL);
279b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(value != NULL);
280b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
281b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_lock(&lock);
2829d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  bool ret = config_has_key(config, section, key);
283b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  if (ret)
2849d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati    *value = config_get_int(config, section, key, *value);
285b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_unlock(&lock);
286b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
287b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  return ret;
2887939ed0c9a50c769e9e648a2d7751e0894b485edzzy}
289b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
2909d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatibool btif_config_set_int(const char *section, const char *key, int value) {
291b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
2929d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  assert(section != NULL);
293b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(key != NULL);
294b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
295b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_lock(&lock);
2969d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  config_set_int(config, section, key, value);
297b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_unlock(&lock);
298b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
299b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  return true;
3007939ed0c9a50c769e9e648a2d7751e0894b485edzzy}
3017939ed0c9a50c769e9e648a2d7751e0894b485edzzy
302ce0bab413c2c1a0a5e9f4a82a6b2833685333bceSharvil Nanavatibool btif_config_get_str(const char *section, const char *key, char *value, int *size_bytes) {
303b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
3049d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  assert(section != NULL);
305b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(key != NULL);
306b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(value != NULL);
307ce0bab413c2c1a0a5e9f4a82a6b2833685333bceSharvil Nanavati  assert(size_bytes != NULL);
308b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
309b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_lock(&lock);
3109d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  const char *stored_value = config_get_string(config, section, key, NULL);
311b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_unlock(&lock);
312b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
313b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  if (!stored_value)
314b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati    return false;
315b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
316ce0bab413c2c1a0a5e9f4a82a6b2833685333bceSharvil Nanavati  strlcpy(value, stored_value, *size_bytes);
317ce0bab413c2c1a0a5e9f4a82a6b2833685333bceSharvil Nanavati  *size_bytes = strlen(value) + 1;
318b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
319b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  return true;
3207939ed0c9a50c769e9e648a2d7751e0894b485edzzy}
321b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
3229d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatibool btif_config_set_str(const char *section, const char *key, const char *value) {
323b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
3249d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  assert(section != NULL);
325b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(key != NULL);
326b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(value != NULL);
327b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
328b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_lock(&lock);
3299d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  config_set_string(config, section, key, value);
330b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_unlock(&lock);
331b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
332b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  return true;
3337939ed0c9a50c769e9e648a2d7751e0894b485edzzy}
334b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
3359d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatibool btif_config_get_bin(const char *section, const char *key, uint8_t *value, size_t *length) {
336b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
3379d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  assert(section != NULL);
338b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(key != NULL);
339b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(value != NULL);
340b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(length != NULL);
341b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
342b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_lock(&lock);
3439d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  const char *value_str = config_get_string(config, section, key, NULL);
344b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_unlock(&lock);
345b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
346b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  if (!value_str)
347b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati    return false;
348b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
349b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  size_t value_len = strlen(value_str);
350b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  if ((value_len % 2) != 0 || *length < (value_len / 2))
351b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati    return false;
352b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
353b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  for (size_t i = 0; i < value_len; ++i)
354b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati    if (!isxdigit(value_str[i]))
355b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati      return false;
356b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
357b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  for (*length = 0; *value_str; value_str += 2, *length += 1)
358b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati    sscanf(value_str, "%02hhx", &value[*length]);
359b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
360b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  return true;
3617939ed0c9a50c769e9e648a2d7751e0894b485edzzy}
3627939ed0c9a50c769e9e648a2d7751e0894b485edzzy
3639d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatisize_t btif_config_get_bin_length(const char *section, const char *key) {
364b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
3659d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  assert(section != NULL);
366b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(key != NULL);
367b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
368b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_lock(&lock);
3699d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  const char *value_str = config_get_string(config, section, key, NULL);
370b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_unlock(&lock);
371b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
372b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  if (!value_str)
373b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati    return 0;
374b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
375b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  size_t value_len = strlen(value_str);
376b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  return ((value_len % 2) != 0) ? 0 : (value_len / 2);
3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3799d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatibool btif_config_set_bin(const char *section, const char *key, const uint8_t *value, size_t length) {
380444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji  const char *lookup = "0123456789abcdef";
381b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
382b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
3839d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  assert(section != NULL);
384b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(key != NULL);
385444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
386444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji  if (length > 0)
387444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji      assert(value != NULL);
388b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
389eae61663a5c44f2a5757ae3df80cbc3b97fa6d60Pavlin Radoslavov  char *str = (char *)osi_calloc(length * 2 + 1);
390b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
391b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  for (size_t i = 0; i < length; ++i) {
392b2f0447afd5db6579e380439ad596519276e91d1Zach Johnson    str[(i * 2) + 0] = lookup[(value[i] >> 4) & 0x0F];
393444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji    str[(i * 2) + 1] = lookup[value[i] & 0x0F];
394b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  }
395b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
396b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_lock(&lock);
3979d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  config_set_string(config, section, key, str);
398b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_unlock(&lock);
399b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
400eae61663a5c44f2a5757ae3df80cbc3b97fa6d60Pavlin Radoslavov  osi_free(str);
401b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  return true;
4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
403b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
404b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavaticonst btif_config_section_iter_t *btif_config_section_begin(void) {
405b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
406b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  return (const btif_config_section_iter_t *)config_section_begin(config);
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
408b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
409b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavaticonst btif_config_section_iter_t *btif_config_section_end(void) {
410b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
411b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  return (const btif_config_section_iter_t *)config_section_end(config);
412689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project}
413b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
414b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavaticonst btif_config_section_iter_t *btif_config_section_next(const btif_config_section_iter_t *section) {
415b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
416b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(section != NULL);
417b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  return (const btif_config_section_iter_t *)config_section_next((const config_section_node_t *)section);
4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
419b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
420b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavaticonst char *btif_config_section_name(const btif_config_section_iter_t *section) {
421b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
422b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(section != NULL);
423b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  return config_section_name((const config_section_node_t *)section);
4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
425b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
4269d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatibool btif_config_remove(const char *section, const char *key) {
427b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
4289d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  assert(section != NULL);
429b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(key != NULL);
430b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
431b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_lock(&lock);
4329d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati  bool ret = config_remove_key(config, section, key);
433b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_unlock(&lock);
434b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
435b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  return ret;
4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
437b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
438b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavativoid btif_config_save(void) {
439b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
440d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen  assert(config_timer != NULL);
441b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
44278bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov  alarm_set(config_timer, CONFIG_SETTLE_PERIOD_MS, timer_config_save_cb, NULL);
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
445b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavativoid btif_config_flush(void) {
446b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
44778bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov  assert(config_timer != NULL);
4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
44978bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov  alarm_cancel(config_timer);
45032b3a8a408b23aa28324ad9f56654c98fe2ac914Srinu Jella  btif_config_write(0, NULL);
4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
45286f97eda524568f2d264186844450db5e56dac36Matthew Xie
453bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panickerbool btif_config_clear(void) {
454aa3be1a696b9ae1142fe9f358ad5f97e99da7892Ajay Panicker  assert(config != NULL);
45578bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov  assert(config_timer != NULL);
456aa3be1a696b9ae1142fe9f358ad5f97e99da7892Ajay Panicker
45778bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov  alarm_cancel(config_timer);
458aa3be1a696b9ae1142fe9f358ad5f97e99da7892Ajay Panicker
459aa3be1a696b9ae1142fe9f358ad5f97e99da7892Ajay Panicker  pthread_mutex_lock(&lock);
460aa3be1a696b9ae1142fe9f358ad5f97e99da7892Ajay Panicker  config_free(config);
461aa3be1a696b9ae1142fe9f358ad5f97e99da7892Ajay Panicker
462aa3be1a696b9ae1142fe9f358ad5f97e99da7892Ajay Panicker  config = config_new_empty();
463aa3be1a696b9ae1142fe9f358ad5f97e99da7892Ajay Panicker  if (config == NULL) {
464aa3be1a696b9ae1142fe9f358ad5f97e99da7892Ajay Panicker    pthread_mutex_unlock(&lock);
465aa3be1a696b9ae1142fe9f358ad5f97e99da7892Ajay Panicker    return false;
466aa3be1a696b9ae1142fe9f358ad5f97e99da7892Ajay Panicker  }
467aa3be1a696b9ae1142fe9f358ad5f97e99da7892Ajay Panicker
4689ca88af1d964c546af1c3dc2c16c4c98071fd5b1Sharvil Nanavati  bool ret = config_save(config, CONFIG_FILE_PATH);
469190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker  btif_config_source = RESET;
470aa3be1a696b9ae1142fe9f358ad5f97e99da7892Ajay Panicker  pthread_mutex_unlock(&lock);
471aa3be1a696b9ae1142fe9f358ad5f97e99da7892Ajay Panicker  return ret;
472aa3be1a696b9ae1142fe9f358ad5f97e99da7892Ajay Panicker}
473aa3be1a696b9ae1142fe9f358ad5f97e99da7892Ajay Panicker
474d77f1999ecece56c1cbb333f4ddc26f0b5bac2c5Marie Janssenstatic void timer_config_save_cb(UNUSED_ATTR void *data) {
47532b3a8a408b23aa28324ad9f56654c98fe2ac914Srinu Jella  // Moving file I/O to btif context instead of timer callback because
47632b3a8a408b23aa28324ad9f56654c98fe2ac914Srinu Jella  // it usually takes a lot of time to be completed, introducing
47732b3a8a408b23aa28324ad9f56654c98fe2ac914Srinu Jella  // delays during A2DP playback causing blips or choppiness.
47832b3a8a408b23aa28324ad9f56654c98fe2ac914Srinu Jella  btif_transfer_context(btif_config_write, 0, NULL, 0, NULL);
479d77f1999ecece56c1cbb333f4ddc26f0b5bac2c5Marie Janssen}
480d77f1999ecece56c1cbb333f4ddc26f0b5bac2c5Marie Janssen
481b7f64bc45dec7f7fec74ceb04874f322b9434bbfMarie Janssenstatic void btif_config_write(UNUSED_ATTR uint16_t event, UNUSED_ATTR char *p_param) {
482b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  assert(config != NULL);
48378bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov  assert(config_timer != NULL);
484b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
485b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  pthread_mutex_lock(&lock);
48679b294d7cb4b48a371dd6698d85e08771ed79eb1Ajay Panicker  rename(CONFIG_FILE_PATH, CONFIG_BACKUP_PATH);
4874cef24d88eb14396011bf31a185d4cab9d0254aaMarie Janssen  config_t *config_paired = config_new_clone(config);
488d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen  btif_config_remove_unpaired(config_paired);
489d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen  config_save(config_paired, CONFIG_FILE_PATH);
4904cef24d88eb14396011bf31a185d4cab9d0254aaMarie Janssen  config_free(config_paired);
491d77f1999ecece56c1cbb333f4ddc26f0b5bac2c5Marie Janssen  pthread_mutex_unlock(&lock);
492d77f1999ecece56c1cbb333f4ddc26f0b5bac2c5Marie Janssen}
49386f97eda524568f2d264186844450db5e56dac36Matthew Xie
494d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssenstatic void btif_config_remove_unpaired(config_t *conf) {
495d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen  assert(conf != NULL);
496bcfdd0ab24357c5dd842540e6c0e8f34ba7aac11Marie Janssen  int paired_devices = 0;
497b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati
498d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen  // The paired config used to carry information about
499d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen  // discovered devices during regular inquiry scans.
500d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen  // We remove these now and cache them in memory instead.
501d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen  const config_section_node_t *snode = config_section_begin(conf);
502d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen  while (snode != config_section_end(conf)) {
503d77f1999ecece56c1cbb333f4ddc26f0b5bac2c5Marie Janssen    const char *section = config_section_name(snode);
504d77f1999ecece56c1cbb333f4ddc26f0b5bac2c5Marie Janssen    if (string_is_bdaddr(section)) {
505d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen      if (!config_has_key(conf, section, "LinkKey") &&
506d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen          !config_has_key(conf, section, "LE_KEY_PENC") &&
507d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen          !config_has_key(conf, section, "LE_KEY_PID") &&
508d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen          !config_has_key(conf, section, "LE_KEY_PCSRK") &&
509d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen          !config_has_key(conf, section, "LE_KEY_LENC") &&
510d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen          !config_has_key(conf, section, "LE_KEY_LCSRK")) {
511d77f1999ecece56c1cbb333f4ddc26f0b5bac2c5Marie Janssen        snode = config_section_next(snode);
512d9ebc239abf77a1133c3456db84444ccbc8d0fddMarie Janssen        config_remove_section(conf, section);
513d77f1999ecece56c1cbb333f4ddc26f0b5bac2c5Marie Janssen        continue;
514d77f1999ecece56c1cbb333f4ddc26f0b5bac2c5Marie Janssen      }
515bcfdd0ab24357c5dd842540e6c0e8f34ba7aac11Marie Janssen      paired_devices++;
516d77f1999ecece56c1cbb333f4ddc26f0b5bac2c5Marie Janssen    }
517d77f1999ecece56c1cbb333f4ddc26f0b5bac2c5Marie Janssen    snode = config_section_next(snode);
518b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati  }
519bcfdd0ab24357c5dd842540e6c0e8f34ba7aac11Marie Janssen
520bcfdd0ab24357c5dd842540e6c0e8f34ba7aac11Marie Janssen  // should only happen once, at initial load time
521bcfdd0ab24357c5dd842540e6c0e8f34ba7aac11Marie Janssen  if (btif_config_devices_loaded == -1)
522bcfdd0ab24357c5dd842540e6c0e8f34ba7aac11Marie Janssen    btif_config_devices_loaded = paired_devices;
523b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati}
524190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker
525190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panickervoid btif_debug_config_dump(int fd) {
526190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker    dprintf(fd, "\nBluetooth Config:\n");
527190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker
528190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker    dprintf(fd, "  Config Source: ");
529190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker    switch(btif_config_source) {
530190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker        case NOT_LOADED:
531190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker            dprintf(fd, "Not loaded\n");
532190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker            break;
533190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker        case ORIGINAL:
534190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker            dprintf(fd, "Original file\n");
535190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker            break;
536190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker        case BACKUP:
537190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker            dprintf(fd, "Backup file\n");
538190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker            break;
5399a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh        case LEGACY:
5409a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh            dprintf(fd, "Legacy file\n");
5419a58e68a98fbe1680535a7e7641de91e89273ad8Alain Vongsouvanh            break;
542190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker        case NEW_FILE:
543190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker            dprintf(fd, "New file\n");
544190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker            break;
545190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker        case RESET:
546190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker            dprintf(fd, "Reset file\n");
547190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker            break;
548190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker    }
549190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker
550bcfdd0ab24357c5dd842540e6c0e8f34ba7aac11Marie Janssen    dprintf(fd, "  Devices loaded: %d\n", btif_config_devices_loaded);
551646134e0a04459f649cb50aa9f3272054630c345Ajay Panicker    dprintf(fd, "  File created/tagged: %s\n", btif_config_time_created);
55272a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker    dprintf(fd, "  File source: %s\n", config_get_string(config, INFO_SECTION,
55372a183d00c7534c80a4deb9fb41d38fd9e9455f6Ajay Panicker                                           FILE_SOURCE, "Original"));
554190cf46ff6937bceff146aec026cf9f53c40e84dAjay Panicker}
555bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panicker
5567b266be449e4f915c419199c2312eb31f70e63bcAjay Panickerstatic void btif_config_remove_restricted(config_t* config) {
5577b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker  assert(config != NULL);
5587b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker
5597b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker  const config_section_node_t *snode = config_section_begin(config);
5607b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker  while (snode != config_section_end(config)) {
5617b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker    const char *section = config_section_name(snode);
5627b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker    if (string_is_bdaddr(section) && config_has_key(config, section, "Restricted")) {
5637b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker        BTIF_TRACE_DEBUG("%s: Removing restricted device %s", __func__, section);
5647b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker        config_remove_section(config, section);
5657b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker    }
5667b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker    snode = config_section_next(snode);
5677b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker  }
5687b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker}
5697b266be449e4f915c419199c2312eb31f70e63bcAjay Panicker
570bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panickerstatic bool is_factory_reset(void) {
571bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panicker  char factory_reset[PROPERTY_VALUE_MAX] = {0};
572b4a42e7b9c277cfd71a575cbdb104013855b80cdBluetooth Build Test  osi_property_get("persist.bluetooth.factoryreset", factory_reset, "false");
573bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panicker  return strncmp(factory_reset, "true", 4) == 0;
574bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panicker}
575bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panicker
576bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panickerstatic void delete_config_files(void) {
577bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panicker  remove(CONFIG_FILE_PATH);
578bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panicker  remove(CONFIG_BACKUP_PATH);
579b4a42e7b9c277cfd71a575cbdb104013855b80cdBluetooth Build Test  osi_property_set("persist.bluetooth.factoryreset", "false");
580bf5c3cb18f16198bc2657cd7a50874d17cd52cc8Ajay Panicker}
581