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