summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarie Janssen <jamuraa@google.com>2015-12-09 10:08:25 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2016-02-16 05:00:27 -0800
commitb20358ca321f22ab073cf2107fef299017943de4 (patch)
tree69b29cf647f284235dedce7bb91e5129a984397d
parentaf69c1e623a79119e9b8180d23671a661bdb1eab (diff)
downloadandroid_system_bt-b20358ca321f22ab073cf2107fef299017943de4.tar.gz
android_system_bt-b20358ca321f22ab073cf2107fef299017943de4.tar.bz2
android_system_bt-b20358ca321f22ab073cf2107fef299017943de4.zip
Fix crashes with lots of discovered LE devices
When loads of devices are discovered a config file which is too large can be written out, which causes the BT daemon to crash on startup. This limits the number of config entries for unpaired devices which are initialized, and prevents a large number from being saved to the filesystem. CRs-Fixed: 953993 Bug: 26071376 Change-Id: I4a74094f57a82b17f94e99a819974b8bc8082184 (cherry picked from commit d77f1999ecece56c1cbb333f4ddc26f0b5bac2c5)
-rw-r--r--btif/src/btif_config.c85
1 files changed, 42 insertions, 43 deletions
diff --git a/btif/src/btif_config.c b/btif/src/btif_config.c
index c94e449f8..aad4fa6b9 100644
--- a/btif/src/btif_config.c
+++ b/btif/src/btif_config.c
@@ -43,8 +43,9 @@ static const char *CONFIG_FILE_PATH = "/data/misc/bluedroid/bt_config.conf";
static const char *LEGACY_CONFIG_FILE_PATH = "/data/misc/bluedroid/bt_config.xml";
static const period_ms_t CONFIG_SETTLE_PERIOD_MS = 3000;
-static void timer_config_saving(void* data);
-static void timer_config_save(UINT16 event, char* p_param);
+static void timer_config_save_cb(void *data);
+static void btif_config_write(void);
+static void btif_config_devcache_cleanup(void);
// TODO(zachoverflow): Move these two functions out, because they are too specific for this file
// {grumpy-cat/no, monty-python/you-make-me-sad}
@@ -109,6 +110,8 @@ static future_t *init(void) {
unlink(LEGACY_CONFIG_FILE_PATH);
}
+ btif_config_devcache_cleanup();
+
// TODO(sharvil): use a non-wake alarm for this once we have
// API support for it. There's no need to wake the system to
// write back to disk.
@@ -348,7 +351,7 @@ void btif_config_save(void) {
assert(alarm_timer != NULL);
assert(config != NULL);
- alarm_set(alarm_timer, CONFIG_SETTLE_PERIOD_MS, timer_config_saving, NULL);
+ alarm_set(alarm_timer, CONFIG_SETTLE_PERIOD_MS, timer_config_save_cb, NULL);
}
void btif_config_flush(void) {
@@ -357,10 +360,7 @@ void btif_config_flush(void) {
alarm_cancel(alarm_timer);
- pthread_mutex_lock(&lock);
- config_save(config, CONFIG_FILE_PATH);
- config_flush(CONFIG_FILE_PATH);
- pthread_mutex_unlock(&lock);
+ btif_config_write();
}
int btif_config_clear(void){
@@ -383,52 +383,51 @@ int btif_config_clear(void){
return ret;
}
-static void timer_config_saving(UNUSED_ATTR void* data) {
- // calling file IO onto btif context instead of timer callback because
- // it usually takes lots of time to be completed timer callback has big
- // delayed during a2dp playback causing blip or choppiness.
- btif_transfer_context(timer_config_save, 0, NULL, 0, NULL);
+static void timer_config_save_cb(UNUSED_ATTR void *data) {
+ btif_config_write();
}
-static void timer_config_save(UNUSED_ATTR UINT16 event, UNUSED_ATTR char* p_param) {
+static void btif_config_write(void) {
assert(config != NULL);
assert(alarm_timer != NULL);
- // Garbage collection process: the config file accumulates
- // cached information about remote devices during regular
- // inquiry scans. We remove some of these junk entries
- // so the file doesn't grow indefinitely. We have to take care
- // to make sure we don't remove information about bonded
- // devices (hence the check for link keys).
- static const size_t CACHE_MAX = 256;
- const char *keys[CACHE_MAX];
- size_t num_keys = 0;
- size_t total_candidates = 0;
+ btif_config_devcache_cleanup();
pthread_mutex_lock(&lock);
- for (const config_section_node_t *snode = config_section_begin(config); snode != config_section_end(config); snode = config_section_next(snode)) {
- const char *section = config_section_name(snode);
- if (!string_is_bdaddr(section))
- continue;
+ config_save(config, CONFIG_FILE_PATH);
+ pthread_mutex_unlock(&lock);
+}
- if (config_has_key(config, section, "LinkKey") ||
- config_has_key(config, section, "LE_KEY_PENC") ||
- config_has_key(config, section, "LE_KEY_PID") ||
- config_has_key(config, section, "LE_KEY_PCSRK") ||
- config_has_key(config, section, "LE_KEY_LENC") ||
- config_has_key(config, section, "LE_KEY_LCSRK"))
- continue;
+static void btif_config_devcache_cleanup(void) {
+ assert(config != NULL);
- if (num_keys < CACHE_MAX)
- keys[num_keys++] = section;
+ // The config accumulates cached information about remote
+ // devices during regular inquiry scans. We remove some of these
+ // so the cache doesn't grow indefinitely.
+ // We don't remove information about bonded devices (which have link keys).
+ static const size_t ADDRS_MAX = 512;
+ size_t total_addrs = 0;
- ++total_candidates;
+ pthread_mutex_lock(&lock);
+ const config_section_node_t *snode = config_section_begin(config);
+ while (snode != config_section_end(config)) {
+ const char *section = config_section_name(snode);
+ if (string_is_bdaddr(section)) {
+ ++total_addrs;
+
+ if ((total_addrs > ADDRS_MAX) &&
+ !config_has_key(config, section, "LinkKey") &&
+ !config_has_key(config, section, "LE_KEY_PENC") &&
+ !config_has_key(config, section, "LE_KEY_PID") &&
+ !config_has_key(config, section, "LE_KEY_PCSRK") &&
+ !config_has_key(config, section, "LE_KEY_LENC") &&
+ !config_has_key(config, section, "LE_KEY_LCSRK")) {
+ snode = config_section_next(snode);
+ config_remove_section(config, section);
+ continue;
+ }
+ }
+ snode = config_section_next(snode);
}
-
- if (total_candidates > CACHE_MAX * 2)
- while (num_keys > 0)
- config_remove_section(config, keys[--num_keys]);
-
- config_save(config, CONFIG_FILE_PATH);
pthread_mutex_unlock(&lock);
}