1 /****************************************************************************** 2 * 3 * Copyright (C) 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 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} 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 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 config_t* config; 119 static alarm_t* config_timer; 120 121 // Module lifecycle functions 122 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, INFO_SECTION, FILE_SOURCE, file_source.c_str()); 158 159 if (!config) { 160 LOG_ERROR(LOG_TAG, "%s unable to allocate a config object.", __func__); 161 goto error; 162 } 163 164 btif_config_remove_unpaired(config); 165 166 // Cleanup temporary pairings if we have left guest mode 167 if (!is_restricted_mode()) btif_config_remove_restricted(config); 168 169 // Read or set config file creation timestamp 170 const char* time_str; 171 time_str = config_get_string(config, INFO_SECTION, FILE_TIMESTAMP, NULL); 172 if (time_str != NULL) { 173 strlcpy(btif_config_time_created, time_str, TIME_STRING_LENGTH); 174 } else { 175 time_t current_time = time(NULL); 176 struct tm* time_created = localtime(¤t_time); 177 strftime(btif_config_time_created, TIME_STRING_LENGTH, TIME_STRING_FORMAT, 178 time_created); 179 config_set_string(config, INFO_SECTION, FILE_TIMESTAMP, 180 btif_config_time_created); 181 } 182 183 // TODO(sharvil): use a non-wake alarm for this once we have 184 // API support for it. There's no need to wake the system to 185 // write back to disk. 186 config_timer = alarm_new("btif.config"); 187 if (!config_timer) { 188 LOG_ERROR(LOG_TAG, "%s unable to create alarm.", __func__); 189 goto error; 190 } 191 192 LOG_EVENT_INT(BT_CONFIG_SOURCE_TAG_NUM, btif_config_source); 193 194 return future_new_immediate(FUTURE_SUCCESS); 195 196 error: 197 alarm_free(config_timer); 198 config_free(config); 199 config_timer = NULL; 200 config = NULL; 201 btif_config_source = NOT_LOADED; 202 return future_new_immediate(FUTURE_FAIL); 203 } 204 205 static config_t* btif_config_open(const char* filename) { 206 config_t* config = config_new(filename); 207 if (!config) return NULL; 208 209 if (!config_has_section(config, "Adapter")) { 210 LOG_ERROR(LOG_TAG, "Config is missing adapter section"); 211 config_free(config); 212 return NULL; 213 } 214 215 return config; 216 } 217 218 static future_t* shut_down(void) { 219 btif_config_flush(); 220 return future_new_immediate(FUTURE_SUCCESS); 221 } 222 223 static future_t* clean_up(void) { 224 btif_config_flush(); 225 226 alarm_free(config_timer); 227 config_timer = NULL; 228 229 std::unique_lock<std::mutex> lock(config_lock); 230 config_free(config); 231 config = NULL; 232 return future_new_immediate(FUTURE_SUCCESS); 233 } 234 235 EXPORT_SYMBOL module_t btif_config_module = {.name = BTIF_CONFIG_MODULE, 236 .init = init, 237 .start_up = NULL, 238 .shut_down = shut_down, 239 .clean_up = clean_up}; 240 241 bool btif_config_has_section(const char* section) { 242 CHECK(config != NULL); 243 CHECK(section != NULL); 244 245 std::unique_lock<std::mutex> lock(config_lock); 246 return config_has_section(config, section); 247 } 248 249 bool btif_config_exist(const char* section, const char* key) { 250 CHECK(config != NULL); 251 CHECK(section != NULL); 252 CHECK(key != NULL); 253 254 std::unique_lock<std::mutex> lock(config_lock); 255 return config_has_key(config, section, key); 256 } 257 258 bool btif_config_get_int(const char* section, const char* key, int* value) { 259 CHECK(config != NULL); 260 CHECK(section != NULL); 261 CHECK(key != NULL); 262 CHECK(value != NULL); 263 264 std::unique_lock<std::mutex> lock(config_lock); 265 bool ret = config_has_key(config, section, key); 266 if (ret) *value = config_get_int(config, section, key, *value); 267 268 return ret; 269 } 270 271 bool btif_config_set_int(const char* section, const char* key, int value) { 272 CHECK(config != NULL); 273 CHECK(section != NULL); 274 CHECK(key != NULL); 275 276 std::unique_lock<std::mutex> lock(config_lock); 277 config_set_int(config, section, key, value); 278 279 return true; 280 } 281 282 bool btif_config_get_str(const char* section, const char* key, char* value, 283 int* size_bytes) { 284 CHECK(config != NULL); 285 CHECK(section != NULL); 286 CHECK(key != NULL); 287 CHECK(value != NULL); 288 CHECK(size_bytes != NULL); 289 290 { 291 std::unique_lock<std::mutex> lock(config_lock); 292 const char* stored_value = config_get_string(config, section, key, NULL); 293 if (!stored_value) return false; 294 strlcpy(value, stored_value, *size_bytes); 295 } 296 297 *size_bytes = strlen(value) + 1; 298 return true; 299 } 300 301 bool btif_config_set_str(const char* section, const char* key, 302 const char* value) { 303 CHECK(config != NULL); 304 CHECK(section != NULL); 305 CHECK(key != NULL); 306 CHECK(value != NULL); 307 308 std::unique_lock<std::mutex> lock(config_lock); 309 config_set_string(config, section, key, value); 310 return true; 311 } 312 313 bool btif_config_get_bin(const char* section, const char* key, uint8_t* value, 314 size_t* length) { 315 CHECK(config != NULL); 316 CHECK(section != NULL); 317 CHECK(key != NULL); 318 CHECK(value != NULL); 319 CHECK(length != NULL); 320 321 std::unique_lock<std::mutex> lock(config_lock); 322 const char* value_str = config_get_string(config, section, key, NULL); 323 324 if (!value_str) return false; 325 326 size_t value_len = strlen(value_str); 327 if ((value_len % 2) != 0 || *length < (value_len / 2)) return false; 328 329 for (size_t i = 0; i < value_len; ++i) 330 if (!isxdigit(value_str[i])) return false; 331 332 for (*length = 0; *value_str; value_str += 2, *length += 1) 333 sscanf(value_str, "%02hhx", &value[*length]); 334 335 return true; 336 } 337 338 size_t btif_config_get_bin_length(const char* section, const char* key) { 339 CHECK(config != NULL); 340 CHECK(section != NULL); 341 CHECK(key != NULL); 342 343 std::unique_lock<std::mutex> lock(config_lock); 344 const char* value_str = config_get_string(config, section, key, NULL); 345 if (!value_str) return 0; 346 347 size_t value_len = strlen(value_str); 348 return ((value_len % 2) != 0) ? 0 : (value_len / 2); 349 } 350 351 bool btif_config_set_bin(const char* section, const char* key, 352 const uint8_t* value, size_t length) { 353 const char* lookup = "0123456789abcdef"; 354 355 CHECK(config != NULL); 356 CHECK(section != NULL); 357 CHECK(key != NULL); 358 359 if (length > 0) CHECK(value != NULL); 360 361 char* str = (char*)osi_calloc(length * 2 + 1); 362 363 for (size_t i = 0; i < length; ++i) { 364 str[(i * 2) + 0] = lookup[(value[i] >> 4) & 0x0F]; 365 str[(i * 2) + 1] = lookup[value[i] & 0x0F]; 366 } 367 368 { 369 std::unique_lock<std::mutex> lock(config_lock); 370 config_set_string(config, section, key, str); 371 } 372 373 osi_free(str); 374 return true; 375 } 376 377 const btif_config_section_iter_t* btif_config_section_begin(void) { 378 CHECK(config != NULL); 379 return (const btif_config_section_iter_t*)config_section_begin(config); 380 } 381 382 const btif_config_section_iter_t* btif_config_section_end(void) { 383 CHECK(config != NULL); 384 return (const btif_config_section_iter_t*)config_section_end(config); 385 } 386 387 const btif_config_section_iter_t* btif_config_section_next( 388 const btif_config_section_iter_t* section) { 389 CHECK(config != NULL); 390 CHECK(section != NULL); 391 return (const btif_config_section_iter_t*)config_section_next( 392 (const config_section_node_t*)section); 393 } 394 395 const char* btif_config_section_name( 396 const btif_config_section_iter_t* section) { 397 CHECK(config != NULL); 398 CHECK(section != NULL); 399 return config_section_name((const config_section_node_t*)section); 400 } 401 402 bool btif_config_remove(const char* section, const char* key) { 403 CHECK(config != NULL); 404 CHECK(section != NULL); 405 CHECK(key != NULL); 406 407 std::unique_lock<std::mutex> lock(config_lock); 408 return config_remove_key(config, section, key); 409 } 410 411 void btif_config_save(void) { 412 CHECK(config != NULL); 413 CHECK(config_timer != NULL); 414 415 alarm_set(config_timer, CONFIG_SETTLE_PERIOD_MS, timer_config_save_cb, NULL); 416 } 417 418 void btif_config_flush(void) { 419 CHECK(config != NULL); 420 CHECK(config_timer != NULL); 421 422 alarm_cancel(config_timer); 423 btif_config_write(0, NULL); 424 } 425 426 bool btif_config_clear(void) { 427 CHECK(config != NULL); 428 CHECK(config_timer != NULL); 429 430 alarm_cancel(config_timer); 431 432 std::unique_lock<std::mutex> lock(config_lock); 433 config_free(config); 434 435 config = config_new_empty(); 436 if (config == NULL) return false; 437 438 bool ret = config_save(config, CONFIG_FILE_PATH); 439 btif_config_source = RESET; 440 return ret; 441 } 442 443 static void timer_config_save_cb(UNUSED_ATTR void* data) { 444 // Moving file I/O to btif context instead of timer callback because 445 // it usually takes a lot of time to be completed, introducing 446 // delays during A2DP playback causing blips or choppiness. 447 btif_transfer_context(btif_config_write, 0, NULL, 0, NULL); 448 } 449 450 static void btif_config_write(UNUSED_ATTR uint16_t event, 451 UNUSED_ATTR char* p_param) { 452 CHECK(config != NULL); 453 CHECK(config_timer != NULL); 454 455 std::unique_lock<std::mutex> lock(config_lock); 456 rename(CONFIG_FILE_PATH, CONFIG_BACKUP_PATH); 457 config_t* config_paired = config_new_clone(config); 458 btif_config_remove_unpaired(config_paired); 459 config_save(config_paired, CONFIG_FILE_PATH); 460 config_free(config_paired); 461 } 462 463 static void btif_config_remove_unpaired(config_t* conf) { 464 CHECK(conf != NULL); 465 int paired_devices = 0; 466 467 // The paired config used to carry information about 468 // discovered devices during regular inquiry scans. 469 // We remove these now and cache them in memory instead. 470 const config_section_node_t* snode = config_section_begin(conf); 471 while (snode != config_section_end(conf)) { 472 const char* section = config_section_name(snode); 473 if (RawAddress::IsValidAddress(section)) { 474 if (!config_has_key(conf, section, "LinkKey") && 475 !config_has_key(conf, section, "LE_KEY_PENC") && 476 !config_has_key(conf, section, "LE_KEY_PID") && 477 !config_has_key(conf, section, "LE_KEY_PCSRK") && 478 !config_has_key(conf, section, "LE_KEY_LENC") && 479 !config_has_key(conf, section, "LE_KEY_LCSRK")) { 480 snode = config_section_next(snode); 481 config_remove_section(conf, section); 482 continue; 483 } 484 paired_devices++; 485 } 486 snode = config_section_next(snode); 487 } 488 489 // should only happen once, at initial load time 490 if (btif_config_devices_loaded == -1) 491 btif_config_devices_loaded = paired_devices; 492 } 493 494 void btif_debug_config_dump(int fd) { 495 dprintf(fd, "\nBluetooth Config:\n"); 496 497 dprintf(fd, " Config Source: "); 498 switch (btif_config_source) { 499 case NOT_LOADED: 500 dprintf(fd, "Not loaded\n"); 501 break; 502 case ORIGINAL: 503 dprintf(fd, "Original file\n"); 504 break; 505 case BACKUP: 506 dprintf(fd, "Backup file\n"); 507 break; 508 case LEGACY: 509 dprintf(fd, "Legacy file\n"); 510 break; 511 case NEW_FILE: 512 dprintf(fd, "New file\n"); 513 break; 514 case RESET: 515 dprintf(fd, "Reset file\n"); 516 break; 517 } 518 519 dprintf(fd, " Devices loaded: %d\n", btif_config_devices_loaded); 520 dprintf(fd, " File created/tagged: %s\n", btif_config_time_created); 521 dprintf(fd, " File source: %s\n", 522 config_get_string(config, INFO_SECTION, FILE_SOURCE, "Original")); 523 } 524 525 static void btif_config_remove_restricted(config_t* config) { 526 CHECK(config != NULL); 527 528 const config_section_node_t* snode = config_section_begin(config); 529 while (snode != config_section_end(config)) { 530 const char* section = config_section_name(snode); 531 if (RawAddress::IsValidAddress(section) && 532 config_has_key(config, section, "Restricted")) { 533 BTIF_TRACE_DEBUG("%s: Removing restricted device %s", __func__, section); 534 config_remove_section(config, section); 535 } 536 snode = config_section_next(snode); 537 } 538 } 539 540 static bool is_factory_reset(void) { 541 char factory_reset[PROPERTY_VALUE_MAX] = {0}; 542 osi_property_get("persist.bluetooth.factoryreset", factory_reset, "false"); 543 return strncmp(factory_reset, "true", 4) == 0; 544 } 545 546 static void delete_config_files(void) { 547 remove(CONFIG_FILE_PATH); 548 remove(CONFIG_BACKUP_PATH); 549 osi_property_set("persist.bluetooth.factoryreset", "false"); 550 } 551