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(&current_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