btif_config.cc revision 9b0fbce37260e69cb116be1cdcbceb1f43bf9346
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 19b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati#define LOG_TAG "bt_btif_config" 20b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 21b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati#include <assert.h> 225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <ctype.h> 23b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati#include <pthread.h> 245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdio.h> 25b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati#include <string.h> 26b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati#include <utils/Log.h> 27b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 28b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati#include "alarm.h" 298a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati#include "bdaddr.h" 305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_config.h" 31b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati#include "btif_config_transcode.h" 325cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen#include "btif_util.h" 33b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati#include "config.h" 349b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson#include "module.h" 35b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati#include "osi.h" 365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 37b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati#include "bd.h" 387939ed0c9a50c769e9e648a2d7751e0894b485edzzy 39b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatistatic const char *CONFIG_FILE_PATH = "/data/misc/bluedroid/bt_config.conf"; 40b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatistatic const char *LEGACY_CONFIG_FILE_PATH = "/data/misc/bluedroid/bt_config.xml"; 41b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatistatic const period_ms_t CONFIG_SETTLE_PERIOD_MS = 3000; 427939ed0c9a50c769e9e648a2d7751e0894b485edzzy 43b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatistatic void timer_config_save(void *data); 44335aa36bca8532874c23c1afe5bfc2aff7fc01a5Mike J. Chen 45b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati// TODO(zachoverflow): Move these two functions out, because they are too specific for this file 46b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati// {grumpy-cat/no, monty-python/you-make-me-sad} 47b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatibool btif_get_device_type(const BD_ADDR bd_addr, int *p_device_type) 4886f97eda524568f2d264186844450db5e56dac36Matthew Xie{ 4986f97eda524568f2d264186844450db5e56dac36Matthew Xie if (p_device_type == NULL) 5086f97eda524568f2d264186844450db5e56dac36Matthew Xie return FALSE; 5186f97eda524568f2d264186844450db5e56dac36Matthew Xie 5286f97eda524568f2d264186844450db5e56dac36Matthew Xie bt_bdaddr_t bda; 5386f97eda524568f2d264186844450db5e56dac36Matthew Xie bdcpy(bda.address, bd_addr); 5486f97eda524568f2d264186844450db5e56dac36Matthew Xie 558a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati bdstr_t bd_addr_str; 568a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati bdaddr_to_string(&bda, bd_addr_str, sizeof(bd_addr_str)); 5786f97eda524568f2d264186844450db5e56dac36Matthew Xie 589d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati if (!btif_config_get_int(bd_addr_str, "DevType", p_device_type)) 5986f97eda524568f2d264186844450db5e56dac36Matthew Xie return FALSE; 6086f97eda524568f2d264186844450db5e56dac36Matthew Xie 6186f97eda524568f2d264186844450db5e56dac36Matthew Xie ALOGD("%s: Device [%s] type %d", __FUNCTION__, bd_addr_str, *p_device_type); 6286f97eda524568f2d264186844450db5e56dac36Matthew Xie return TRUE; 6386f97eda524568f2d264186844450db5e56dac36Matthew Xie} 6486f97eda524568f2d264186844450db5e56dac36Matthew Xie 65b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatibool btif_get_address_type(const BD_ADDR bd_addr, int *p_addr_type) 6686f97eda524568f2d264186844450db5e56dac36Matthew Xie{ 6786f97eda524568f2d264186844450db5e56dac36Matthew Xie if (p_addr_type == NULL) 6886f97eda524568f2d264186844450db5e56dac36Matthew Xie return FALSE; 6986f97eda524568f2d264186844450db5e56dac36Matthew Xie 7086f97eda524568f2d264186844450db5e56dac36Matthew Xie bt_bdaddr_t bda; 7186f97eda524568f2d264186844450db5e56dac36Matthew Xie bdcpy(bda.address, bd_addr); 7286f97eda524568f2d264186844450db5e56dac36Matthew Xie 738a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati bdstr_t bd_addr_str; 748a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati bdaddr_to_string(&bda, bd_addr_str, sizeof(bd_addr_str)); 7586f97eda524568f2d264186844450db5e56dac36Matthew Xie 769d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati if (!btif_config_get_int(bd_addr_str, "AddrType", p_addr_type)) 7786f97eda524568f2d264186844450db5e56dac36Matthew Xie return FALSE; 7886f97eda524568f2d264186844450db5e56dac36Matthew Xie 7986f97eda524568f2d264186844450db5e56dac36Matthew Xie ALOGD("%s: Device [%s] address type %d", __FUNCTION__, bd_addr_str, *p_addr_type); 8086f97eda524568f2d264186844450db5e56dac36Matthew Xie return TRUE; 8186f97eda524568f2d264186844450db5e56dac36Matthew Xie} 8286f97eda524568f2d264186844450db5e56dac36Matthew Xie 83b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatistatic pthread_mutex_t lock; // protects operations on |config|. 84b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatistatic config_t *config; 85b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatistatic alarm_t *alarm_timer; 86b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 879b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson// Module lifecycle functions 889b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson 899b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnsonstatic future_t *init(void) { 90b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_init(&lock, NULL); 91b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati config = config_new(CONFIG_FILE_PATH); 92b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati if (!config) { 93b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati ALOGW("%s unable to load config file; attempting to transcode legacy file.", __func__); 94b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati config = btif_config_transcode(LEGACY_CONFIG_FILE_PATH); 95b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati if (!config) { 96b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati ALOGW("%s unable to transcode legacy file, starting unconfigured.", __func__); 97b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati config = config_new_empty(); 98b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati if (!config) { 99b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati ALOGE("%s unable to allocate a config object.", __func__); 100b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati goto error; 101b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati } 1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 103b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 104b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati if (config_save(config, CONFIG_FILE_PATH)) 105b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati unlink(LEGACY_CONFIG_FILE_PATH); 106b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati } 107b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 108b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati // TODO(sharvil): use a non-wake alarm for this once we have 1099b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson // API support for it. There's no need to wake the system to 110b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati // write back to disk. 111b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati alarm_timer = alarm_new(); 112b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati if (!alarm_timer) { 113b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati ALOGE("%s unable to create alarm.", __func__); 114b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati goto error; 115b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati } 116b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 1179b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson return future_new_immediate(FUTURE_SUCCESS); 118b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 119b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatierror:; 120b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati alarm_free(alarm_timer); 121b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati config_free(config); 122b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_destroy(&lock); 123b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati alarm_timer = NULL; 124b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati config = NULL; 1259b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson return future_new_immediate(FUTURE_FAIL); 1269b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson} 1279b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson 1289b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnsonstatic future_t *shut_down(void) { 1299b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson btif_config_flush(); 1309b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson return future_new_immediate(FUTURE_SUCCESS); 1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 132b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 1339b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnsonstatic future_t *clean_up(void) { 134b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati btif_config_flush(); 135b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 136b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati alarm_free(alarm_timer); 137b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati config_free(config); 138b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_destroy(&lock); 139b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati alarm_timer = NULL; 140b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati config = NULL; 1419b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson return future_new_immediate(FUTURE_SUCCESS); 1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 143b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 1449b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnsonconst module_t btif_config_module = { 1459b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson .name = BTIF_CONFIG_MODULE, 1469b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson .init = init, 1479b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson .start_up = NULL, 1489b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson .shut_down = shut_down, 1499b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson .clean_up = clean_up, 1509b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson .dependencies = { 1519b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson NULL 1529b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson } 1539b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson}; 1549b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson 1559d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatibool btif_config_has_section(const char *section) { 156b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 1579d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati assert(section != NULL); 158b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 159b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_lock(&lock); 1609d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati bool ret = config_has_section(config, section); 161b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_unlock(&lock); 162b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 163b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return ret; 1647939ed0c9a50c769e9e648a2d7751e0894b485edzzy} 165b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 1669d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatibool btif_config_exist(const char *section, const char *key) { 167b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 1689d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati assert(section != NULL); 169b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(key != NULL); 170b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 171b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_lock(&lock); 1729d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati bool ret = config_has_key(config, section, key); 173b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_unlock(&lock); 174b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 175b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return ret; 1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 177b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 1789d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatibool btif_config_get_int(const char *section, const char *key, int *value) { 179b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 1809d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati assert(section != NULL); 181b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(key != NULL); 182b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(value != NULL); 183b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 184b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_lock(&lock); 1859d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati bool ret = config_has_key(config, section, key); 186b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati if (ret) 1879d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati *value = config_get_int(config, section, key, *value); 188b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_unlock(&lock); 189b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 190b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return ret; 1917939ed0c9a50c769e9e648a2d7751e0894b485edzzy} 192b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 1939d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatibool btif_config_set_int(const char *section, const char *key, int value) { 194b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 1959d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati assert(section != NULL); 196b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(key != NULL); 197b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 198b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_lock(&lock); 1999d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati config_set_int(config, section, key, value); 200b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_unlock(&lock); 201b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 202b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return true; 2037939ed0c9a50c769e9e648a2d7751e0894b485edzzy} 2047939ed0c9a50c769e9e648a2d7751e0894b485edzzy 205ce0bab413c2c1a0a5e9f4a82a6b2833685333bceSharvil Nanavatibool btif_config_get_str(const char *section, const char *key, char *value, int *size_bytes) { 206b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 2079d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati assert(section != NULL); 208b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(key != NULL); 209b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(value != NULL); 210ce0bab413c2c1a0a5e9f4a82a6b2833685333bceSharvil Nanavati assert(size_bytes != NULL); 211b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 212b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_lock(&lock); 2139d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati const char *stored_value = config_get_string(config, section, key, NULL); 214b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_unlock(&lock); 215b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 216b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati if (!stored_value) 217b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return false; 218b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 219ce0bab413c2c1a0a5e9f4a82a6b2833685333bceSharvil Nanavati strlcpy(value, stored_value, *size_bytes); 220ce0bab413c2c1a0a5e9f4a82a6b2833685333bceSharvil Nanavati *size_bytes = strlen(value) + 1; 221b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 222b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return true; 2237939ed0c9a50c769e9e648a2d7751e0894b485edzzy} 224b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 2259d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatibool btif_config_set_str(const char *section, const char *key, const char *value) { 226b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 2279d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati assert(section != NULL); 228b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(key != NULL); 229b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(value != NULL); 230b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 231b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_lock(&lock); 2329d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati config_set_string(config, section, key, value); 233b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_unlock(&lock); 234b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 235b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return true; 2367939ed0c9a50c769e9e648a2d7751e0894b485edzzy} 237b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 2389d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatibool btif_config_get_bin(const char *section, const char *key, uint8_t *value, size_t *length) { 239b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 2409d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati assert(section != NULL); 241b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(key != NULL); 242b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(value != NULL); 243b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(length != NULL); 244b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 245b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_lock(&lock); 2469d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati const char *value_str = config_get_string(config, section, key, NULL); 247b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_unlock(&lock); 248b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 249b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati if (!value_str) 250b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return false; 251b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 252b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati size_t value_len = strlen(value_str); 253b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati if ((value_len % 2) != 0 || *length < (value_len / 2)) 254b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return false; 255b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 256b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati for (size_t i = 0; i < value_len; ++i) 257b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati if (!isxdigit(value_str[i])) 258b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return false; 259b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 260b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati for (*length = 0; *value_str; value_str += 2, *length += 1) 261b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati sscanf(value_str, "%02hhx", &value[*length]); 262b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 263b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return true; 2647939ed0c9a50c769e9e648a2d7751e0894b485edzzy} 2657939ed0c9a50c769e9e648a2d7751e0894b485edzzy 2669d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatisize_t btif_config_get_bin_length(const char *section, const char *key) { 267b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 2689d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati assert(section != NULL); 269b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(key != NULL); 270b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 271b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_lock(&lock); 2729d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati const char *value_str = config_get_string(config, section, key, NULL); 273b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_unlock(&lock); 274b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 275b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati if (!value_str) 276b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return 0; 277b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 278b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati size_t value_len = strlen(value_str); 279b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return ((value_len % 2) != 0) ? 0 : (value_len / 2); 2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2829d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatibool btif_config_set_bin(const char *section, const char *key, const uint8_t *value, size_t length) { 283b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati static const char *lookup = "0123456789abcdef"; 284b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 285b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 2869d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati assert(section != NULL); 287b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(key != NULL); 288b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(value != NULL); 289b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 290b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati char *str = (char *)calloc(length * 2 + 1, 1); 291b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati if (!str) 292b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return false; 293b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 294b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati for (size_t i = 0; i < length; ++i) { 295b2f0447afd5db6579e380439ad596519276e91d1Zach Johnson str[(i * 2) + 0] = lookup[(value[i] >> 4) & 0x0F]; 296b2f0447afd5db6579e380439ad596519276e91d1Zach Johnson str[(i * 2) + 1] = lookup[(value[i] >> 0) & 0x0F]; 297b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati } 298b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 299b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_lock(&lock); 3009d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati config_set_string(config, section, key, str); 301b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_unlock(&lock); 302b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 303b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati free(str); 304b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return true; 3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 306b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 307b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavaticonst btif_config_section_iter_t *btif_config_section_begin(void) { 308b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 309b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return (const btif_config_section_iter_t *)config_section_begin(config); 3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 311b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 312b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavaticonst btif_config_section_iter_t *btif_config_section_end(void) { 313b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 314b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return (const btif_config_section_iter_t *)config_section_end(config); 315689d66b6559dcb3a0ad7f6cc33b6129e50910253The Android Open Source Project} 316b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 317b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavaticonst btif_config_section_iter_t *btif_config_section_next(const btif_config_section_iter_t *section) { 318b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 319b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(section != NULL); 320b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return (const btif_config_section_iter_t *)config_section_next((const config_section_node_t *)section); 3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 322b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 323b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavaticonst char *btif_config_section_name(const btif_config_section_iter_t *section) { 324b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 325b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(section != NULL); 326b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return config_section_name((const config_section_node_t *)section); 3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 328b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 3299d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavatibool btif_config_remove(const char *section, const char *key) { 330b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 3319d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati assert(section != NULL); 332b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(key != NULL); 333b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 334b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_lock(&lock); 3359d52f88bfc07556cb01ab3055f5b1242c9b467aaSharvil Nanavati bool ret = config_remove_key(config, section, key); 336b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_unlock(&lock); 337b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 338b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati return ret; 3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 340b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 341b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavativoid btif_config_save(void) { 342b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(alarm_timer != NULL); 343b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 344b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 345b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati alarm_set(alarm_timer, CONFIG_SETTLE_PERIOD_MS, timer_config_save, NULL); 3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 348b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavativoid btif_config_flush(void) { 349b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 350b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(alarm_timer != NULL); 3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 352b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati alarm_cancel(alarm_timer); 3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 354b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_lock(&lock); 355b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati config_save(config, CONFIG_FILE_PATH); 356b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_unlock(&lock); 3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 35886f97eda524568f2d264186844450db5e56dac36Matthew Xie 359b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavatistatic void timer_config_save(UNUSED_ATTR void *data) { 360b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(config != NULL); 361b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati assert(alarm_timer != NULL); 362b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 363b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati // Garbage collection process: the config file accumulates 364b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati // cached information about remote devices during regular 365b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati // inquiry scans. We remove some of these junk entries 366b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati // so the file doesn't grow indefinitely. We have to take care 367b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati // to make sure we don't remove information about bonded 368b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati // devices (hence the check for link keys). 369b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati static const size_t CACHE_MAX = 256; 370b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati const char *keys[CACHE_MAX]; 371b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati size_t num_keys = 0; 372b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati size_t total_candidates = 0; 373b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 374b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_lock(&lock); 375b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati for (const config_section_node_t *snode = config_section_begin(config); snode != config_section_end(config); snode = config_section_next(snode)) { 376b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati const char *section = config_section_name(snode); 3778a6a89faa942aed4f176b0c98402d01c8bdd6aa6Sharvil Nanavati if (!string_is_bdaddr(section)) 378b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati continue; 37986f97eda524568f2d264186844450db5e56dac36Matthew Xie 380b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati if (config_has_key(config, section, "LinkKey") || 381b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati config_has_key(config, section, "LE_KEY_PENC") || 382b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati config_has_key(config, section, "LE_KEY_PID") || 383b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati config_has_key(config, section, "LE_KEY_PCSRK") || 384b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati config_has_key(config, section, "LE_KEY_LENC") || 385b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati config_has_key(config, section, "LE_KEY_LCSRK")) 386b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati continue; 387b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 388b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati if (num_keys < CACHE_MAX) 389b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati keys[num_keys++] = section; 390b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 391b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati ++total_candidates; 392b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati } 393b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 394b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati if (total_candidates > CACHE_MAX * 2) 395b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati while (num_keys > 0) 396b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati config_remove_section(config, keys[--num_keys]); 397b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati 398b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati config_save(config, CONFIG_FILE_PATH); 399b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati pthread_mutex_unlock(&lock); 400b95c4ef4ac9e86953050a7ae6b3b4260df935713Sharvil Nanavati} 401