1 /****************************************************************************** 2 * 3 * Copyright 2014 Google, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 #define LOG_TAG "bt_btif_config" 20 21 #include "btif_config.h" 22 23 #include <base/logging.h> 24 #include <ctype.h> 25 #include <stdio.h> 26 #include <string.h> 27 #include <time.h> 28 #include <unistd.h> 29 #include <string> 30 31 #include <mutex> 32 33 #include "bt_types.h" 34 #include "btcore/include/module.h" 35 #include "btif_api.h" 36 #include "btif_common.h" 37 #include "btif_config_transcode.h" 38 #include "btif_util.h" 39 #include "osi/include/alarm.h" 40 #include "osi/include/allocator.h" 41 #include "osi/include/compat.h" 42 #include "osi/include/config.h" 43 #include "osi/include/log.h" 44 #include "osi/include/osi.h" 45 #include "osi/include/properties.h" 46 47 #define BT_CONFIG_SOURCE_TAG_NUM 1010001 48 49 #define INFO_SECTION "Info" 50 #define FILE_TIMESTAMP "TimeCreated" 51 #define FILE_SOURCE "FileSource" 52 #define TIME_STRING_LENGTH sizeof("YYYY-MM-DD HH:MM:SS") 53 static const char* TIME_STRING_FORMAT = "%Y-%m-%d %H:%M:%S"; 54 55 // TODO(armansito): Find a better way than searching by a hardcoded path. 56 #if defined(OS_GENERIC) 57 static const char* CONFIG_FILE_PATH = "bt_config.conf"; 58 static const char* CONFIG_BACKUP_PATH = "bt_config.bak"; 59 static const char* CONFIG_LEGACY_FILE_PATH = "bt_config.xml"; 60 #else // !defined(OS_GENERIC) 61 static const char* CONFIG_FILE_PATH = "/data/misc/bluedroid/bt_config.conf"; 62 static const char* CONFIG_BACKUP_PATH = "/data/misc/bluedroid/bt_config.bak"; 63 static const char* CONFIG_LEGACY_FILE_PATH = 64 "/data/misc/bluedroid/bt_config.xml"; 65 #endif // defined(OS_GENERIC) 66 static const period_ms_t CONFIG_SETTLE_PERIOD_MS = 3000; 67 68 static void timer_config_save_cb(void* data); 69 static void btif_config_write(uint16_t event, char* p_param); 70 static bool is_factory_reset(void); 71 static void delete_config_files(void); 72 static void btif_config_remove_unpaired(config_t* config); 73 static void btif_config_remove_restricted(config_t* config); 74 static std::unique_ptr<config_t> btif_config_open(const char* filename); 75 76 static enum ConfigSource { 77 NOT_LOADED, 78 ORIGINAL, 79 BACKUP, 80 LEGACY, 81 NEW_FILE, 82 RESET 83 } btif_config_source = NOT_LOADED; 84 85 static int btif_config_devices_loaded = -1; 86 static char btif_config_time_created[TIME_STRING_LENGTH]; 87 88 // TODO(zachoverflow): Move these two functions out, because they are too 89 // specific for this file 90 // {grumpy-cat/no, monty-python/you-make-me-sad} btif_get_device_type(const RawAddress & bda,int * p_device_type)91 bool btif_get_device_type(const RawAddress& bda, int* p_device_type) { 92 if (p_device_type == NULL) return false; 93 94 std::string addrstr = bda.ToString(); 95 const char* bd_addr_str = addrstr.c_str(); 96 97 if (!btif_config_get_int(bd_addr_str, "DevType", p_device_type)) return false; 98 99 LOG_DEBUG(LOG_TAG, "%s: Device [%s] type %d", __func__, bd_addr_str, 100 *p_device_type); 101 return true; 102 } 103 btif_get_address_type(const RawAddress & bda,int * p_addr_type)104 bool btif_get_address_type(const RawAddress& bda, int* p_addr_type) { 105 if (p_addr_type == NULL) return false; 106 107 std::string addrstr = bda.ToString(); 108 const char* bd_addr_str = addrstr.c_str(); 109 110 if (!btif_config_get_int(bd_addr_str, "AddrType", p_addr_type)) return false; 111 112 LOG_DEBUG(LOG_TAG, "%s: Device [%s] address type %d", __func__, bd_addr_str, 113 *p_addr_type); 114 return true; 115 } 116 117 static std::mutex config_lock; // protects operations on |config|. 118 static std::unique_ptr<config_t> config; 119 static alarm_t* config_timer; 120 121 // Module lifecycle functions 122 init(void)123 static future_t* init(void) { 124 std::unique_lock<std::mutex> lock(config_lock); 125 126 if (is_factory_reset()) delete_config_files(); 127 128 std::string file_source; 129 130 config = btif_config_open(CONFIG_FILE_PATH); 131 btif_config_source = ORIGINAL; 132 if (!config) { 133 LOG_WARN(LOG_TAG, "%s unable to load config file: %s; using backup.", 134 __func__, CONFIG_FILE_PATH); 135 config = btif_config_open(CONFIG_BACKUP_PATH); 136 btif_config_source = BACKUP; 137 file_source = "Backup"; 138 } 139 if (!config) { 140 LOG_WARN(LOG_TAG, 141 "%s unable to load backup; attempting to transcode legacy file.", 142 __func__); 143 config = btif_config_transcode(CONFIG_LEGACY_FILE_PATH); 144 btif_config_source = LEGACY; 145 file_source = "Legacy"; 146 } 147 if (!config) { 148 LOG_ERROR(LOG_TAG, 149 "%s unable to transcode legacy file; creating empty config.", 150 __func__); 151 config = config_new_empty(); 152 btif_config_source = NEW_FILE; 153 file_source = "Empty"; 154 } 155 156 if (!file_source.empty()) 157 config_set_string(config.get(), INFO_SECTION, FILE_SOURCE, file_source); 158 159 btif_config_remove_unpaired(config.get()); 160 161 // Cleanup temporary pairings if we have left guest mode 162 if (!is_restricted_mode()) btif_config_remove_restricted(config.get()); 163 164 // Read or set config file creation timestamp 165 const std::string* time_str; 166 time_str = config_get_string(*config, INFO_SECTION, FILE_TIMESTAMP, NULL); 167 if (time_str != NULL) { 168 strlcpy(btif_config_time_created, time_str->c_str(), TIME_STRING_LENGTH); 169 } else { 170 time_t current_time = time(NULL); 171 struct tm* time_created = localtime(¤t_time); 172 strftime(btif_config_time_created, TIME_STRING_LENGTH, TIME_STRING_FORMAT, 173 time_created); 174 config_set_string(config.get(), INFO_SECTION, FILE_TIMESTAMP, 175 btif_config_time_created); 176 } 177 178 // TODO(sharvil): use a non-wake alarm for this once we have 179 // API support for it. There's no need to wake the system to 180 // write back to disk. 181 config_timer = alarm_new("btif.config"); 182 if (!config_timer) { 183 LOG_ERROR(LOG_TAG, "%s unable to create alarm.", __func__); 184 goto error; 185 } 186 187 LOG_EVENT_INT(BT_CONFIG_SOURCE_TAG_NUM, btif_config_source); 188 189 return future_new_immediate(FUTURE_SUCCESS); 190 191 error: 192 alarm_free(config_timer); 193 config.reset(); 194 config_timer = NULL; 195 btif_config_source = NOT_LOADED; 196 return future_new_immediate(FUTURE_FAIL); 197 } 198 btif_config_open(const char * filename)199 static std::unique_ptr<config_t> btif_config_open(const char* filename) { 200 std::unique_ptr<config_t> config = config_new(filename); 201 if (!config) return nullptr; 202 203 if (!config_has_section(*config, "Adapter")) { 204 LOG_ERROR(LOG_TAG, "Config is missing adapter section"); 205 return nullptr; 206 } 207 208 return config; 209 } 210 shut_down(void)211 static future_t* shut_down(void) { 212 btif_config_flush(); 213 return future_new_immediate(FUTURE_SUCCESS); 214 } 215 clean_up(void)216 static future_t* clean_up(void) { 217 btif_config_flush(); 218 219 alarm_free(config_timer); 220 config_timer = NULL; 221 222 std::unique_lock<std::mutex> lock(config_lock); 223 config.reset(); 224 return future_new_immediate(FUTURE_SUCCESS); 225 } 226 227 EXPORT_SYMBOL module_t btif_config_module = {.name = BTIF_CONFIG_MODULE, 228 .init = init, 229 .start_up = NULL, 230 .shut_down = shut_down, 231 .clean_up = clean_up}; 232 btif_config_has_section(const char * section)233 bool btif_config_has_section(const char* section) { 234 CHECK(config != NULL); 235 CHECK(section != NULL); 236 237 std::unique_lock<std::mutex> lock(config_lock); 238 return config_has_section(*config, section); 239 } 240 btif_config_exist(const std::string & section,const std::string & key)241 bool btif_config_exist(const std::string& section, const std::string& key) { 242 CHECK(config != NULL); 243 244 std::unique_lock<std::mutex> lock(config_lock); 245 return config_has_key(*config, section, key); 246 } 247 btif_config_get_int(const std::string & section,const std::string & key,int * value)248 bool btif_config_get_int(const std::string& section, const std::string& key, 249 int* value) { 250 CHECK(config != NULL); 251 CHECK(value != NULL); 252 253 std::unique_lock<std::mutex> lock(config_lock); 254 bool ret = config_has_key(*config, section, key); 255 if (ret) *value = config_get_int(*config, section, key, *value); 256 257 return ret; 258 } 259 btif_config_set_int(const std::string & section,const std::string & key,int value)260 bool btif_config_set_int(const std::string& section, const std::string& key, 261 int value) { 262 CHECK(config != NULL); 263 264 std::unique_lock<std::mutex> lock(config_lock); 265 config_set_int(config.get(), section, key, value); 266 267 return true; 268 } 269 btif_config_get_uint64(const std::string & section,const std::string & key,uint64_t * value)270 bool btif_config_get_uint64(const std::string& section, const std::string& key, 271 uint64_t* value) { 272 CHECK(config != NULL); 273 CHECK(value != NULL); 274 275 std::unique_lock<std::mutex> lock(config_lock); 276 bool ret = config_has_key(*config, section, key); 277 if (ret) *value = config_get_uint64(*config, section, key, *value); 278 279 return ret; 280 } 281 btif_config_set_uint64(const std::string & section,const std::string & key,uint64_t value)282 bool btif_config_set_uint64(const std::string& section, const std::string& key, 283 uint64_t value) { 284 CHECK(config != NULL); 285 286 std::unique_lock<std::mutex> lock(config_lock); 287 config_set_uint64(config.get(), section, key, value); 288 289 return true; 290 } 291 btif_config_get_str(const std::string & section,const std::string & key,char * value,int * size_bytes)292 bool btif_config_get_str(const std::string& section, const std::string& key, 293 char* value, int* size_bytes) { 294 CHECK(config != NULL); 295 CHECK(value != NULL); 296 CHECK(size_bytes != NULL); 297 298 { 299 std::unique_lock<std::mutex> lock(config_lock); 300 const std::string* stored_value = 301 config_get_string(*config, section, key, NULL); 302 if (!stored_value) return false; 303 strlcpy(value, stored_value->c_str(), *size_bytes); 304 } 305 306 *size_bytes = strlen(value) + 1; 307 return true; 308 } 309 btif_config_set_str(const std::string & section,const std::string & key,const std::string & value)310 bool btif_config_set_str(const std::string& section, const std::string& key, 311 const std::string& value) { 312 CHECK(config != NULL); 313 314 std::unique_lock<std::mutex> lock(config_lock); 315 config_set_string(config.get(), section, key, value); 316 return true; 317 } 318 btif_config_get_bin(const std::string & section,const std::string & key,uint8_t * value,size_t * length)319 bool btif_config_get_bin(const std::string& section, const std::string& key, 320 uint8_t* value, size_t* length) { 321 CHECK(config != NULL); 322 CHECK(value != NULL); 323 CHECK(length != NULL); 324 325 std::unique_lock<std::mutex> lock(config_lock); 326 const std::string* value_str = config_get_string(*config, section, key, NULL); 327 328 if (!value_str) return false; 329 330 size_t value_len = value_str->length(); 331 if ((value_len % 2) != 0 || *length < (value_len / 2)) return false; 332 333 for (size_t i = 0; i < value_len; ++i) 334 if (!isxdigit(value_str->c_str()[i])) return false; 335 336 const char* ptr = value_str->c_str(); 337 for (*length = 0; *ptr; ptr += 2, *length += 1) 338 sscanf(ptr, "%02hhx", &value[*length]); 339 340 return true; 341 } 342 btif_config_get_bin_length(const std::string & section,const std::string & key)343 size_t btif_config_get_bin_length(const std::string& section, 344 const std::string& key) { 345 CHECK(config != NULL); 346 347 std::unique_lock<std::mutex> lock(config_lock); 348 const std::string* value_str = config_get_string(*config, section, key, NULL); 349 if (!value_str) return 0; 350 351 size_t value_len = value_str->length(); 352 return ((value_len % 2) != 0) ? 0 : (value_len / 2); 353 } 354 btif_config_set_bin(const std::string & section,const std::string & key,const uint8_t * value,size_t length)355 bool btif_config_set_bin(const std::string& section, const std::string& key, 356 const uint8_t* value, size_t length) { 357 const char* lookup = "0123456789abcdef"; 358 359 CHECK(config != NULL); 360 361 if (length > 0) CHECK(value != NULL); 362 363 char* str = (char*)osi_calloc(length * 2 + 1); 364 365 for (size_t i = 0; i < length; ++i) { 366 str[(i * 2) + 0] = lookup[(value[i] >> 4) & 0x0F]; 367 str[(i * 2) + 1] = lookup[value[i] & 0x0F]; 368 } 369 370 { 371 std::unique_lock<std::mutex> lock(config_lock); 372 config_set_string(config.get(), section, key, str); 373 } 374 375 osi_free(str); 376 return true; 377 } 378 btif_config_sections()379 std::list<section_t>& btif_config_sections() { return config->sections; } 380 btif_config_remove(const std::string & section,const std::string & key)381 bool btif_config_remove(const std::string& section, const std::string& key) { 382 CHECK(config != NULL); 383 384 std::unique_lock<std::mutex> lock(config_lock); 385 return config_remove_key(config.get(), section, key); 386 } 387 btif_config_save(void)388 void btif_config_save(void) { 389 CHECK(config != NULL); 390 CHECK(config_timer != NULL); 391 392 alarm_set(config_timer, CONFIG_SETTLE_PERIOD_MS, timer_config_save_cb, NULL); 393 } 394 btif_config_flush(void)395 void btif_config_flush(void) { 396 CHECK(config != NULL); 397 CHECK(config_timer != NULL); 398 399 alarm_cancel(config_timer); 400 btif_config_write(0, NULL); 401 } 402 btif_config_clear(void)403 bool btif_config_clear(void) { 404 CHECK(config != NULL); 405 CHECK(config_timer != NULL); 406 407 alarm_cancel(config_timer); 408 409 std::unique_lock<std::mutex> lock(config_lock); 410 411 config = config_new_empty(); 412 413 bool ret = config_save(*config, CONFIG_FILE_PATH); 414 btif_config_source = RESET; 415 return ret; 416 } 417 timer_config_save_cb(UNUSED_ATTR void * data)418 static void timer_config_save_cb(UNUSED_ATTR void* data) { 419 // Moving file I/O to btif context instead of timer callback because 420 // it usually takes a lot of time to be completed, introducing 421 // delays during A2DP playback causing blips or choppiness. 422 btif_transfer_context(btif_config_write, 0, NULL, 0, NULL); 423 } 424 btif_config_write(UNUSED_ATTR uint16_t event,UNUSED_ATTR char * p_param)425 static void btif_config_write(UNUSED_ATTR uint16_t event, 426 UNUSED_ATTR char* p_param) { 427 CHECK(config != NULL); 428 CHECK(config_timer != NULL); 429 430 std::unique_lock<std::mutex> lock(config_lock); 431 rename(CONFIG_FILE_PATH, CONFIG_BACKUP_PATH); 432 std::unique_ptr<config_t> config_paired = config_new_clone(*config); 433 btif_config_remove_unpaired(config_paired.get()); 434 config_save(*config_paired, CONFIG_FILE_PATH); 435 } 436 btif_config_remove_unpaired(config_t * conf)437 static void btif_config_remove_unpaired(config_t* conf) { 438 CHECK(conf != NULL); 439 int paired_devices = 0; 440 441 // The paired config used to carry information about 442 // discovered devices during regular inquiry scans. 443 // We remove these now and cache them in memory instead. 444 for (auto it = conf->sections.begin(); it != conf->sections.end();) { 445 std::string& section = it->name; 446 if (RawAddress::IsValidAddress(section)) { 447 // TODO: config_has_key loop thorugh all data, maybe just make it so we 448 // loop just once ? 449 if (!config_has_key(*conf, section, "LinkKey") && 450 !config_has_key(*conf, section, "LE_KEY_PENC") && 451 !config_has_key(*conf, section, "LE_KEY_PID") && 452 !config_has_key(*conf, section, "LE_KEY_PCSRK") && 453 !config_has_key(*conf, section, "LE_KEY_LENC") && 454 !config_has_key(*conf, section, "LE_KEY_LCSRK")) { 455 it = conf->sections.erase(it); 456 continue; 457 } 458 paired_devices++; 459 } 460 it++; 461 } 462 463 // should only happen once, at initial load time 464 if (btif_config_devices_loaded == -1) 465 btif_config_devices_loaded = paired_devices; 466 } 467 btif_debug_config_dump(int fd)468 void btif_debug_config_dump(int fd) { 469 dprintf(fd, "\nBluetooth Config:\n"); 470 471 dprintf(fd, " Config Source: "); 472 switch (btif_config_source) { 473 case NOT_LOADED: 474 dprintf(fd, "Not loaded\n"); 475 break; 476 case ORIGINAL: 477 dprintf(fd, "Original file\n"); 478 break; 479 case BACKUP: 480 dprintf(fd, "Backup file\n"); 481 break; 482 case LEGACY: 483 dprintf(fd, "Legacy file\n"); 484 break; 485 case NEW_FILE: 486 dprintf(fd, "New file\n"); 487 break; 488 case RESET: 489 dprintf(fd, "Reset file\n"); 490 break; 491 } 492 493 std::string original = "Original"; 494 dprintf(fd, " Devices loaded: %d\n", btif_config_devices_loaded); 495 dprintf(fd, " File created/tagged: %s\n", btif_config_time_created); 496 dprintf(fd, " File source: %s\n", 497 config_get_string(*config, INFO_SECTION, FILE_SOURCE, &original) 498 ->c_str()); 499 } 500 btif_config_remove_restricted(config_t * config)501 static void btif_config_remove_restricted(config_t* config) { 502 CHECK(config != NULL); 503 504 for (auto it = config->sections.begin(); it != config->sections.end();) { 505 const std::string& section = it->name; 506 if (RawAddress::IsValidAddress(section) && 507 config_has_key(*config, section, "Restricted")) { 508 BTIF_TRACE_DEBUG("%s: Removing restricted device %s", __func__, 509 section.c_str()); 510 it = config->sections.erase(it); 511 continue; 512 } 513 it++; 514 } 515 } 516 is_factory_reset(void)517 static bool is_factory_reset(void) { 518 char factory_reset[PROPERTY_VALUE_MAX] = {0}; 519 osi_property_get("persist.bluetooth.factoryreset", factory_reset, "false"); 520 return strncmp(factory_reset, "true", 4) == 0; 521 } 522 delete_config_files(void)523 static void delete_config_files(void) { 524 remove(CONFIG_FILE_PATH); 525 remove(CONFIG_BACKUP_PATH); 526 osi_property_set("persist.bluetooth.factoryreset", "false"); 527 } 528