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 <unistd.h>
24 #include <cctype>
25 #include <cstdio>
26 #include <cstring>
27 #include <ctime>
28 #include <functional>
29 #include <mutex>
30 #include <sstream>
31 #include <string>
32 #include <unordered_map>
33
34 #include <private/android_filesystem_config.h>
35
36 #include <openssl/rand.h>
37
38 #include <base/logging.h>
39
40 #include "btcore/include/module.h"
41 #include "btif_api.h"
42 #include "btif_common.h"
43 #include "btif_config_cache.h"
44 #include "btif_config_transcode.h"
45 #include "btif_keystore.h"
46 #include "common/address_obfuscator.h"
47 #include "common/metric_id_allocator.h"
48 #include "main/shim/config.h"
49 #include "main/shim/shim.h"
50 #include "osi/include/alarm.h"
51 #include "osi/include/allocator.h"
52 #include "osi/include/compat.h"
53 #include "osi/include/config.h"
54 #include "osi/include/log.h"
55 #include "osi/include/osi.h"
56 #include "osi/include/properties.h"
57 #include "raw_address.h"
58
59 #define BT_CONFIG_SOURCE_TAG_NUM 1010001
60 #define TEMPORARY_SECTION_CAPACITY 10000
61
62 #define INFO_SECTION "Info"
63 #define FILE_TIMESTAMP "TimeCreated"
64 #define FILE_SOURCE "FileSource"
65 #define TIME_STRING_LENGTH sizeof("YYYY-MM-DD HH:MM:SS")
66 #define DISABLED "disabled"
67 static const char* TIME_STRING_FORMAT = "%Y-%m-%d %H:%M:%S";
68
69 #define BT_CONFIG_METRICS_SECTION "Metrics"
70 #define BT_CONFIG_METRICS_SALT_256BIT "Salt256Bit"
71 #define BT_CONFIG_METRICS_ID_KEY "MetricsId"
72
73 using bluetooth::bluetooth_keystore::BluetoothKeystoreInterface;
74 using bluetooth::common::AddressObfuscator;
75 using bluetooth::common::MetricIdAllocator;
76
77 // TODO(armansito): Find a better way than searching by a hardcoded path.
78 #if defined(OS_GENERIC)
79 static const char* CONFIG_FILE_PATH = "bt_config.conf";
80 static const char* CONFIG_BACKUP_PATH = "bt_config.bak";
81 static const char* CONFIG_LEGACY_FILE_PATH = "bt_config.xml";
82 #else // !defined(OS_GENERIC)
83 static const char* CONFIG_FILE_PATH = "/data/misc/bluedroid/bt_config.conf";
84 static const char* CONFIG_BACKUP_PATH = "/data/misc/bluedroid/bt_config.bak";
85 static const char* CONFIG_LEGACY_FILE_PATH =
86 "/data/misc/bluedroid/bt_config.xml";
87 #endif // defined(OS_GENERIC)
88 static const uint64_t CONFIG_SETTLE_PERIOD_MS = 3000;
89
90 static void timer_config_save_cb(void* data);
91 static void btif_config_write(uint16_t event, char* p_param);
92 static bool is_factory_reset(void);
93 static void delete_config_files(void);
94 static std::unique_ptr<config_t> btif_config_open(const char* filename);
95
96 // Key attestation
config_checksum_pass(int check_bit)97 static bool config_checksum_pass(int check_bit) {
98 return ((get_niap_config_compare_result() & check_bit) == check_bit);
99 }
btif_is_niap_mode()100 static bool btif_is_niap_mode() {
101 return getuid() == AID_BLUETOOTH && is_niap_mode();
102 }
103 static bool btif_in_encrypt_key_name_list(std::string key);
104
105 static const int CONFIG_FILE_COMPARE_PASS = 1;
106 static const int CONFIG_BACKUP_COMPARE_PASS = 2;
107 static const std::string ENCRYPTED_STR = "encrypted";
108 static const std::string CONFIG_FILE_PREFIX = "bt_config-origin";
109 static const std::string CONFIG_FILE_HASH = "hash";
110 static const int ENCRYPT_KEY_NAME_LIST_SIZE = 7;
111 static const std::string encrypt_key_name_list[] = {
112 "LinkKey", "LE_KEY_PENC", "LE_KEY_PID", "LE_KEY_LID",
113 "LE_KEY_PCSRK", "LE_KEY_LENC", "LE_KEY_LCSRK"};
114
115 static enum ConfigSource {
116 NOT_LOADED,
117 ORIGINAL,
118 BACKUP,
119 LEGACY,
120 NEW_FILE,
121 RESET
122 } btif_config_source = NOT_LOADED;
123
124 static char btif_config_time_created[TIME_STRING_LENGTH];
125
get_bluetooth_keystore_interface()126 static BluetoothKeystoreInterface* get_bluetooth_keystore_interface() {
127 return bluetooth::bluetooth_keystore::getBluetoothKeystoreInterface();
128 }
129
130 // TODO(zachoverflow): Move these two functions out, because they are too
131 // specific for this file
132 // {grumpy-cat/no, monty-python/you-make-me-sad}
btif_get_device_type(const RawAddress & bda,int * p_device_type)133 bool btif_get_device_type(const RawAddress& bda, int* p_device_type) {
134 if (p_device_type == NULL) return false;
135
136 std::string addrstr = bda.ToString();
137 const char* bd_addr_str = addrstr.c_str();
138
139 if (!btif_config_get_int(bd_addr_str, "DevType", p_device_type)) return false;
140
141 LOG_DEBUG("%s: Device [%s] type %d", __func__, bd_addr_str, *p_device_type);
142 return true;
143 }
144
btif_get_address_type(const RawAddress & bda,int * p_addr_type)145 bool btif_get_address_type(const RawAddress& bda, int* p_addr_type) {
146 if (p_addr_type == NULL) return false;
147
148 std::string addrstr = bda.ToString();
149 const char* bd_addr_str = addrstr.c_str();
150
151 if (!btif_config_get_int(bd_addr_str, "AddrType", p_addr_type)) return false;
152
153 LOG_DEBUG("%s: Device [%s] address type %d", __func__, bd_addr_str,
154 *p_addr_type);
155 return true;
156 }
157
158 /**
159 * Read metrics salt from config file, if salt is invalid or does not exist,
160 * generate new one and save it to config
161 */
read_or_set_metrics_salt()162 static void read_or_set_metrics_salt() {
163 AddressObfuscator::Octet32 metrics_salt = {};
164 size_t metrics_salt_length = metrics_salt.size();
165 if (!btif_config_get_bin(BT_CONFIG_METRICS_SECTION,
166 BT_CONFIG_METRICS_SALT_256BIT, metrics_salt.data(),
167 &metrics_salt_length)) {
168 LOG(WARNING) << __func__ << ": Failed to read metrics salt from config";
169 // Invalidate salt
170 metrics_salt.fill(0);
171 }
172 if (metrics_salt_length != metrics_salt.size()) {
173 LOG(ERROR) << __func__ << ": Metrics salt length incorrect, "
174 << metrics_salt_length << " instead of " << metrics_salt.size();
175 // Invalidate salt
176 metrics_salt.fill(0);
177 }
178 if (!AddressObfuscator::IsSaltValid(metrics_salt)) {
179 LOG(INFO) << __func__ << ": Metrics salt is not invalid, creating new one";
180 if (RAND_bytes(metrics_salt.data(), metrics_salt.size()) != 1) {
181 LOG(FATAL) << __func__ << "Failed to generate salt for metrics";
182 }
183 if (!btif_config_set_bin(BT_CONFIG_METRICS_SECTION,
184 BT_CONFIG_METRICS_SALT_256BIT, metrics_salt.data(),
185 metrics_salt.size())) {
186 LOG(FATAL) << __func__ << "Failed to write metrics salt to config";
187 }
188 }
189 AddressObfuscator::GetInstance()->Initialize(metrics_salt);
190 }
191
192 /**
193 * Initialize metric id allocator by reading metric_id from config by mac
194 * address. If there is no metric id for a mac address, then allocate it a new
195 * metric id.
196 */
init_metric_id_allocator()197 static void init_metric_id_allocator() {
198 std::unordered_map<RawAddress, int> paired_device_map;
199
200 // When user update the system, there will be devices paired with older
201 // version of android without a metric id.
202 std::vector<RawAddress> addresses_without_id;
203
204 for (const auto& mac_address : btif_config_get_paired_devices()) {
205 auto addr_str = mac_address.ToString();
206 // if the section name is a mac address
207 bool is_valid_id_found = false;
208 if (btif_config_exist(addr_str, BT_CONFIG_METRICS_ID_KEY)) {
209 // there is one metric id under this mac_address
210 int id = 0;
211 btif_config_get_int(addr_str, BT_CONFIG_METRICS_ID_KEY, &id);
212 if (MetricIdAllocator::IsValidId(id)) {
213 paired_device_map[mac_address] = id;
214 is_valid_id_found = true;
215 }
216 }
217 if (!is_valid_id_found) {
218 addresses_without_id.push_back(mac_address);
219 }
220 }
221
222 // Initialize MetricIdAllocator
223 MetricIdAllocator::Callback save_device_callback =
224 [](const RawAddress& address, const int id) {
225 return btif_config_set_int(address.ToString(), BT_CONFIG_METRICS_ID_KEY,
226 id);
227 };
228 MetricIdAllocator::Callback forget_device_callback =
229 [](const RawAddress& address, const int id) {
230 return btif_config_remove(address.ToString(), BT_CONFIG_METRICS_ID_KEY);
231 };
232 if (!MetricIdAllocator::GetInstance().Init(
233 paired_device_map, std::move(save_device_callback),
234 std::move(forget_device_callback))) {
235 LOG(FATAL) << __func__ << "Failed to initialize MetricIdAllocator";
236 }
237
238 // Add device_without_id
239 for (auto& address : addresses_without_id) {
240 MetricIdAllocator::GetInstance().AllocateId(address);
241 MetricIdAllocator::GetInstance().SaveDevice(address);
242 }
243 }
244
245 static std::recursive_mutex config_lock; // protects operations on |config|.
246 static alarm_t* config_timer;
247
248 // limited btif config cache capacity
249 static BtifConfigCache btif_config_cache(TEMPORARY_SECTION_CAPACITY);
250
251 // Module lifecycle functions
252
init(void)253 static future_t* init(void) {
254 if (bluetooth::shim::is_gd_shim_enabled()) {
255 CHECK(bluetooth::shim::is_gd_stack_started_up());
256 // TODO (b/158035889) Migrate metrics module to GD
257 read_or_set_metrics_salt();
258 init_metric_id_allocator();
259 return future_new_immediate(FUTURE_SUCCESS);
260 }
261 std::unique_lock<std::recursive_mutex> lock(config_lock);
262 std::unique_ptr<config_t> config;
263
264 if (is_factory_reset()) delete_config_files();
265
266 std::string file_source;
267
268 if (config_checksum_pass(CONFIG_FILE_COMPARE_PASS)) {
269 config = btif_config_open(CONFIG_FILE_PATH);
270 btif_config_source = ORIGINAL;
271 }
272 if (!config) {
273 LOG_WARN("%s unable to load config file: %s; using backup.", __func__,
274 CONFIG_FILE_PATH);
275 if (config_checksum_pass(CONFIG_BACKUP_COMPARE_PASS)) {
276 config = btif_config_open(CONFIG_BACKUP_PATH);
277 btif_config_source = BACKUP;
278 file_source = "Backup";
279 }
280 }
281 if (!config) {
282 LOG_WARN("%s unable to load backup; attempting to transcode legacy file.",
283 __func__);
284 config = btif_config_transcode(CONFIG_LEGACY_FILE_PATH);
285 btif_config_source = LEGACY;
286 file_source = "Legacy";
287 }
288 if (!config) {
289 LOG_ERROR("%s unable to transcode legacy file; creating empty config.",
290 __func__);
291 config = config_new_empty();
292 btif_config_source = NEW_FILE;
293 file_source = "Empty";
294 }
295
296 // move persistent config data from btif_config file to btif config cache
297 btif_config_cache.Init(std::move(config));
298
299 if (!file_source.empty()) {
300 btif_config_cache.SetString(INFO_SECTION, FILE_SOURCE, file_source);
301 }
302
303 // Cleanup temporary pairings if we have left guest mode
304 if (!is_restricted_mode()) {
305 btif_config_cache.RemovePersistentSectionsWithKey("Restricted");
306 }
307
308 // Read or set config file creation timestamp
309 auto time_str = btif_config_cache.GetString(INFO_SECTION, FILE_TIMESTAMP);
310 if (!time_str) {
311 time_t current_time = time(NULL);
312 struct tm* time_created = localtime(¤t_time);
313 strftime(btif_config_time_created, TIME_STRING_LENGTH, TIME_STRING_FORMAT,
314 time_created);
315 btif_config_cache.SetString(INFO_SECTION, FILE_TIMESTAMP,
316 btif_config_time_created);
317 } else {
318 strlcpy(btif_config_time_created, time_str->c_str(), TIME_STRING_LENGTH);
319 }
320
321 // Read or set metrics 256 bit hashing salt
322 read_or_set_metrics_salt();
323
324 // Initialize MetricIdAllocator
325 init_metric_id_allocator();
326
327 // TODO(sharvil): use a non-wake alarm for this once we have
328 // API support for it. There's no need to wake the system to
329 // write back to disk.
330 config_timer = alarm_new("btif.config");
331 if (!config_timer) {
332 LOG_ERROR("%s unable to create alarm.", __func__);
333 goto error;
334 }
335
336 LOG_EVENT_INT(BT_CONFIG_SOURCE_TAG_NUM, btif_config_source);
337
338 return future_new_immediate(FUTURE_SUCCESS);
339
340 error:
341 alarm_free(config_timer);
342 config.reset();
343 btif_config_cache.Clear();
344 config_timer = NULL;
345 btif_config_source = NOT_LOADED;
346 return future_new_immediate(FUTURE_FAIL);
347 }
348
btif_config_open(const char * filename)349 static std::unique_ptr<config_t> btif_config_open(const char* filename) {
350 std::unique_ptr<config_t> config = config_new(filename);
351 if (!config) return nullptr;
352
353 if (!config_has_section(*config, "Adapter")) {
354 LOG_ERROR("Config is missing adapter section");
355 return nullptr;
356 }
357
358 return config;
359 }
360
shut_down(void)361 static future_t* shut_down(void) {
362 btif_config_flush();
363 return future_new_immediate(FUTURE_SUCCESS);
364 }
365
clean_up(void)366 static future_t* clean_up(void) {
367 if (bluetooth::shim::is_gd_shim_enabled()) {
368 CHECK(bluetooth::shim::is_gd_stack_started_up());
369 // GD storage module cleanup by itself
370 std::unique_lock<std::recursive_mutex> lock(config_lock);
371 MetricIdAllocator::GetInstance().Close();
372 return future_new_immediate(FUTURE_SUCCESS);
373 }
374 btif_config_flush();
375
376 alarm_free(config_timer);
377 config_timer = NULL;
378
379 std::unique_lock<std::recursive_mutex> lock(config_lock);
380 get_bluetooth_keystore_interface()->clear_map();
381 MetricIdAllocator::GetInstance().Close();
382 btif_config_cache.Clear();
383 return future_new_immediate(FUTURE_SUCCESS);
384 }
385
386 EXPORT_SYMBOL module_t btif_config_module = {.name = BTIF_CONFIG_MODULE,
387 .init = init,
388 .start_up = NULL,
389 .shut_down = shut_down,
390 .clean_up = clean_up};
391
btif_config_exist(const std::string & section,const std::string & key)392 bool btif_config_exist(const std::string& section, const std::string& key) {
393 if (bluetooth::shim::is_gd_shim_enabled()) {
394 CHECK(bluetooth::shim::is_gd_stack_started_up());
395 return bluetooth::shim::BtifConfigInterface::HasProperty(section, key);
396 }
397 std::unique_lock<std::recursive_mutex> lock(config_lock);
398 return btif_config_cache.HasKey(section, key);
399 }
400
btif_config_get_int(const std::string & section,const std::string & key,int * value)401 bool btif_config_get_int(const std::string& section, const std::string& key,
402 int* value) {
403 if (bluetooth::shim::is_gd_shim_enabled()) {
404 CHECK(bluetooth::shim::is_gd_stack_started_up());
405 return bluetooth::shim::BtifConfigInterface::GetInt(section, key, value);
406 }
407 CHECK(value != NULL);
408 std::unique_lock<std::recursive_mutex> lock(config_lock);
409 auto ret = btif_config_cache.GetInt(section, key);
410 if (!ret) {
411 return false;
412 }
413 *value = *ret;
414 return true;
415 }
416
btif_config_set_int(const std::string & section,const std::string & key,int value)417 bool btif_config_set_int(const std::string& section, const std::string& key,
418 int value) {
419 if (bluetooth::shim::is_gd_shim_enabled()) {
420 CHECK(bluetooth::shim::is_gd_stack_started_up());
421 return bluetooth::shim::BtifConfigInterface::SetInt(section, key, value);
422 }
423 std::unique_lock<std::recursive_mutex> lock(config_lock);
424 btif_config_cache.SetInt(section, key, value);
425 return true;
426 }
427
btif_config_get_uint64(const std::string & section,const std::string & key,uint64_t * value)428 bool btif_config_get_uint64(const std::string& section, const std::string& key,
429 uint64_t* value) {
430 if (bluetooth::shim::is_gd_shim_enabled()) {
431 CHECK(bluetooth::shim::is_gd_stack_started_up());
432 return bluetooth::shim::BtifConfigInterface::GetUint64(section, key, value);
433 }
434 CHECK(value != NULL);
435 std::unique_lock<std::recursive_mutex> lock(config_lock);
436 auto ret = btif_config_cache.GetUint64(section, key);
437 if (!ret) {
438 return false;
439 }
440 *value = *ret;
441 return true;
442 }
443
btif_config_set_uint64(const std::string & section,const std::string & key,uint64_t value)444 bool btif_config_set_uint64(const std::string& section, const std::string& key,
445 uint64_t value) {
446 if (bluetooth::shim::is_gd_shim_enabled()) {
447 CHECK(bluetooth::shim::is_gd_stack_started_up());
448 return bluetooth::shim::BtifConfigInterface::SetUint64(section, key, value);
449 }
450 std::unique_lock<std::recursive_mutex> lock(config_lock);
451 btif_config_cache.SetUint64(section, key, value);
452 return true;
453 }
454
btif_config_get_str(const std::string & section,const std::string & key,char * value,int * size_bytes)455 bool btif_config_get_str(const std::string& section, const std::string& key,
456 char* value, int* size_bytes) {
457 if (bluetooth::shim::is_gd_shim_enabled()) {
458 CHECK(bluetooth::shim::is_gd_stack_started_up());
459 return bluetooth::shim::BtifConfigInterface::GetStr(section, key, value,
460 size_bytes);
461 }
462 CHECK(value != NULL);
463 CHECK(size_bytes != NULL);
464
465 {
466 std::unique_lock<std::recursive_mutex> lock(config_lock);
467 auto stored_value = btif_config_cache.GetString(section, key);
468 if (!stored_value) return false;
469 strlcpy(value, stored_value->c_str(), *size_bytes);
470 }
471 *size_bytes = strlen(value) + 1;
472 return true;
473 }
474
btif_config_set_str(const std::string & section,const std::string & key,const std::string & value)475 bool btif_config_set_str(const std::string& section, const std::string& key,
476 const std::string& value) {
477 if (bluetooth::shim::is_gd_shim_enabled()) {
478 CHECK(bluetooth::shim::is_gd_stack_started_up());
479 return bluetooth::shim::BtifConfigInterface::SetStr(section, key, value);
480 }
481 std::unique_lock<std::recursive_mutex> lock(config_lock);
482 btif_config_cache.SetString(section, key, value);
483 return true;
484 }
485
btif_in_encrypt_key_name_list(std::string key)486 static bool btif_in_encrypt_key_name_list(std::string key) {
487 return std::find(encrypt_key_name_list,
488 encrypt_key_name_list + ENCRYPT_KEY_NAME_LIST_SIZE,
489 key) != (encrypt_key_name_list + ENCRYPT_KEY_NAME_LIST_SIZE);
490 }
491
btif_config_get_bin(const std::string & section,const std::string & key,uint8_t * value,size_t * length)492 bool btif_config_get_bin(const std::string& section, const std::string& key,
493 uint8_t* value, size_t* length) {
494 if (bluetooth::shim::is_gd_shim_enabled()) {
495 CHECK(bluetooth::shim::is_gd_stack_started_up());
496 return bluetooth::shim::BtifConfigInterface::GetBin(section, key, value,
497 length);
498 }
499 CHECK(value != NULL);
500 CHECK(length != NULL);
501
502 std::unique_lock<std::recursive_mutex> lock(config_lock);
503 const std::string* value_str;
504 auto value_str_from_config = btif_config_cache.GetString(section, key);
505
506 if (!value_str_from_config) {
507 VLOG(1) << __func__ << ": cannot find string for section " << section
508 << ", key " << key;
509 return false;
510 }
511
512 bool in_encrypt_key_name_list = btif_in_encrypt_key_name_list(key);
513 bool is_key_encrypted = *value_str_from_config == ENCRYPTED_STR;
514 std::string string;
515
516 if (!value_str_from_config->empty() && in_encrypt_key_name_list &&
517 is_key_encrypted) {
518 string = get_bluetooth_keystore_interface()->get_key(section + "-" + key);
519 value_str = &string;
520 } else {
521 value_str = &value_str_from_config.value();
522 }
523
524 size_t value_len = value_str->length();
525 if ((value_len % 2) != 0 || *length < (value_len / 2)) {
526 LOG(WARNING) << ": value size not divisible by 2, size is " << value_len;
527 return false;
528 }
529
530 for (size_t i = 0; i < value_len; ++i)
531 if (!isxdigit(value_str->c_str()[i])) {
532 LOG(WARNING) << ": value is not hex digit";
533 return false;
534 }
535
536 const char* ptr = value_str->c_str();
537 for (*length = 0; *ptr; ptr += 2, *length += 1) {
538 sscanf(ptr, "%02hhx", &value[*length]);
539 }
540
541 if (btif_is_niap_mode()) {
542 if (!value_str_from_config->empty() && in_encrypt_key_name_list &&
543 !is_key_encrypted) {
544 get_bluetooth_keystore_interface()->set_encrypt_key_or_remove_key(
545 section + "-" + key, *value_str_from_config);
546 btif_config_cache.SetString(section, key, ENCRYPTED_STR);
547 }
548 } else {
549 if (in_encrypt_key_name_list && is_key_encrypted) {
550 btif_config_cache.SetString(section, key, *value_str);
551 }
552 }
553
554 return true;
555 }
556
btif_config_get_bin_length(const std::string & section,const std::string & key)557 size_t btif_config_get_bin_length(const std::string& section,
558 const std::string& key) {
559 if (bluetooth::shim::is_gd_shim_enabled()) {
560 CHECK(bluetooth::shim::is_gd_stack_started_up());
561 return bluetooth::shim::BtifConfigInterface::GetBinLength(section, key);
562 }
563 std::unique_lock<std::recursive_mutex> lock(config_lock);
564 auto value_str = btif_config_cache.GetString(section, key);
565 if (!value_str) return 0;
566 size_t value_len = value_str->length();
567 return ((value_len % 2) != 0) ? 0 : (value_len / 2);
568 }
569
btif_config_set_bin(const std::string & section,const std::string & key,const uint8_t * value,size_t length)570 bool btif_config_set_bin(const std::string& section, const std::string& key,
571 const uint8_t* value, size_t length) {
572 if (bluetooth::shim::is_gd_shim_enabled()) {
573 CHECK(bluetooth::shim::is_gd_stack_started_up());
574 return bluetooth::shim::BtifConfigInterface::SetBin(section, key, value,
575 length);
576 }
577 const char* lookup = "0123456789abcdef";
578 if (length > 0) CHECK(value != NULL);
579
580 size_t max_value = ((size_t)-1);
581 if (((max_value - 1) / 2) < length) {
582 LOG(ERROR) << __func__ << ": length too long";
583 return false;
584 }
585
586 char* str = (char*)osi_calloc(length * 2 + 1);
587
588 for (size_t i = 0; i < length; ++i) {
589 str[(i * 2) + 0] = lookup[(value[i] >> 4) & 0x0F];
590 str[(i * 2) + 1] = lookup[value[i] & 0x0F];
591 }
592
593 std::string value_str;
594 if ((length > 0) && btif_is_niap_mode() &&
595 btif_in_encrypt_key_name_list(key)) {
596 get_bluetooth_keystore_interface()->set_encrypt_key_or_remove_key(
597 section + "-" + key, str);
598 value_str = ENCRYPTED_STR;
599 } else {
600 value_str = str;
601 }
602
603 {
604 std::unique_lock<std::recursive_mutex> lock(config_lock);
605 btif_config_cache.SetString(section, key, value_str);
606 }
607
608 osi_free(str);
609 return true;
610 }
611
btif_config_get_paired_devices()612 std::vector<RawAddress> btif_config_get_paired_devices() {
613 std::vector<std::string> names;
614 if (bluetooth::shim::is_gd_shim_enabled()) {
615 CHECK(bluetooth::shim::is_gd_stack_started_up());
616 names = bluetooth::shim::BtifConfigInterface::GetPersistentDevices();
617 } else {
618 std::unique_lock<std::recursive_mutex> lock(config_lock);
619 names = btif_config_cache.GetPersistentSectionNames();
620 }
621 std::vector<RawAddress> result;
622 result.reserve(names.size());
623 for (const auto& name : names) {
624 RawAddress addr = {};
625 if (!RawAddress::FromString(name, addr)) {
626 LOG(WARNING) << __func__ << ": " << name << " is not a valid address";
627 continue;
628 }
629 result.emplace_back(addr);
630 }
631 return result;
632 }
633
btif_config_remove(const std::string & section,const std::string & key)634 bool btif_config_remove(const std::string& section, const std::string& key) {
635 if (bluetooth::shim::is_gd_shim_enabled()) {
636 CHECK(bluetooth::shim::is_gd_stack_started_up());
637 return bluetooth::shim::BtifConfigInterface::RemoveProperty(section, key);
638 }
639 if (is_niap_mode() && btif_in_encrypt_key_name_list(key)) {
640 get_bluetooth_keystore_interface()->set_encrypt_key_or_remove_key(
641 section + "-" + key, "");
642 }
643 std::unique_lock<std::recursive_mutex> lock(config_lock);
644 return btif_config_cache.RemoveKey(section, key);
645 }
646
btif_config_save(void)647 void btif_config_save(void) {
648 if (bluetooth::shim::is_gd_shim_enabled()) {
649 CHECK(bluetooth::shim::is_gd_stack_started_up());
650 bluetooth::shim::BtifConfigInterface::Save();
651 return;
652 }
653 CHECK(config_timer != NULL);
654
655 alarm_set(config_timer, CONFIG_SETTLE_PERIOD_MS, timer_config_save_cb, NULL);
656 }
657
btif_config_flush(void)658 void btif_config_flush(void) {
659 if (bluetooth::shim::is_gd_shim_enabled()) {
660 CHECK(bluetooth::shim::is_gd_stack_started_up());
661 bluetooth::shim::BtifConfigInterface::Flush();
662 return;
663 }
664 CHECK(config_timer != NULL);
665
666 alarm_cancel(config_timer);
667 btif_config_write(0, NULL);
668 }
669
btif_config_clear(void)670 bool btif_config_clear(void) {
671 if (bluetooth::shim::is_gd_shim_enabled()) {
672 CHECK(bluetooth::shim::is_gd_stack_started_up());
673 bluetooth::shim::BtifConfigInterface::Clear();
674 bluetooth::shim::BtifConfigInterface::Save();
675 return true;
676 }
677 CHECK(config_timer != NULL);
678
679 alarm_cancel(config_timer);
680
681 std::unique_lock<std::recursive_mutex> lock(config_lock);
682
683 btif_config_cache.Clear();
684 bool ret =
685 config_save(btif_config_cache.PersistentSectionCopy(), CONFIG_FILE_PATH);
686 btif_config_source = RESET;
687
688 return ret;
689 }
690
timer_config_save_cb(UNUSED_ATTR void * data)691 static void timer_config_save_cb(UNUSED_ATTR void* data) {
692 // Moving file I/O to btif context instead of timer callback because
693 // it usually takes a lot of time to be completed, introducing
694 // delays during A2DP playback causing blips or choppiness.
695 btif_transfer_context(btif_config_write, 0, NULL, 0, NULL);
696 }
697
btif_config_write(UNUSED_ATTR uint16_t event,UNUSED_ATTR char * p_param)698 static void btif_config_write(UNUSED_ATTR uint16_t event,
699 UNUSED_ATTR char* p_param) {
700 CHECK(config_timer != NULL);
701
702 std::unique_lock<std::recursive_mutex> lock(config_lock);
703 rename(CONFIG_FILE_PATH, CONFIG_BACKUP_PATH);
704 config_save(btif_config_cache.PersistentSectionCopy(), CONFIG_FILE_PATH);
705 if (btif_is_niap_mode()) {
706 get_bluetooth_keystore_interface()->set_encrypt_key_or_remove_key(
707 CONFIG_FILE_PREFIX, CONFIG_FILE_HASH);
708 }
709 }
710
btif_debug_config_dump(int fd)711 void btif_debug_config_dump(int fd) {
712 dprintf(fd, "\nBluetooth Config:\n");
713
714 dprintf(fd, " Config Source: ");
715 switch (btif_config_source) {
716 case NOT_LOADED:
717 dprintf(fd, "Not loaded\n");
718 break;
719 case ORIGINAL:
720 dprintf(fd, "Original file\n");
721 break;
722 case BACKUP:
723 dprintf(fd, "Backup file\n");
724 break;
725 case LEGACY:
726 dprintf(fd, "Legacy file\n");
727 break;
728 case NEW_FILE:
729 dprintf(fd, "New file\n");
730 break;
731 case RESET:
732 dprintf(fd, "Reset file\n");
733 break;
734 }
735
736 std::optional<std::string> file_source;
737 if (bluetooth::shim::is_gd_stack_started_up()) {
738 CHECK(bluetooth::shim::is_gd_shim_enabled());
739 file_source =
740 bluetooth::shim::BtifConfigInterface::GetStr(INFO_SECTION, FILE_SOURCE);
741 } else {
742 file_source = btif_config_cache.GetString(INFO_SECTION, FILE_SOURCE);
743 }
744 if (!file_source) {
745 file_source.emplace("Original");
746 }
747 auto devices = btif_config_cache.GetPersistentSectionNames();
748 dprintf(fd, " Devices loaded: %zu\n", devices.size());
749 dprintf(fd, " File created/tagged: %s\n", btif_config_time_created);
750 dprintf(fd, " File source: %s\n", file_source->c_str());
751 }
752
is_factory_reset(void)753 static bool is_factory_reset(void) {
754 char factory_reset[PROPERTY_VALUE_MAX] = {0};
755 osi_property_get("persist.bluetooth.factoryreset", factory_reset, "false");
756 return strncmp(factory_reset, "true", 4) == 0;
757 }
758
delete_config_files(void)759 static void delete_config_files(void) {
760 remove(CONFIG_FILE_PATH);
761 remove(CONFIG_BACKUP_PATH);
762 osi_property_set("persist.bluetooth.factoryreset", "false");
763 }
764