Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6790325e authored by Marie Janssen's avatar Marie Janssen Committed by android-build-merger
Browse files

Fix crashes with lots of discovered LE devices

am: 24777604

* commit '24777604':
  Fix crashes with lots of discovered LE devices
parents e078a622 24777604
Loading
Loading
Loading
Loading
+44 −36
Original line number Diff line number Diff line
@@ -42,7 +42,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_save(void *data);
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}
@@ -107,6 +109,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.
@@ -346,7 +350,7 @@ void btif_config_save(void) {
  assert(alarm_timer != NULL);
  assert(config != NULL);

  alarm_set(alarm_timer, CONFIG_SETTLE_PERIOD_MS, timer_config_save, NULL);
  alarm_set(alarm_timer, CONFIG_SETTLE_PERIOD_MS, timer_config_save_cb, NULL);
}

void btif_config_flush(void) {
@@ -355,9 +359,7 @@ void btif_config_flush(void) {

  alarm_cancel(alarm_timer);

  pthread_mutex_lock(&lock);
  config_save(config, CONFIG_FILE_PATH);
  pthread_mutex_unlock(&lock);
  btif_config_write();
}

int btif_config_clear(void){
@@ -380,45 +382,51 @@ int btif_config_clear(void){
  return ret;
}

static void timer_config_save(UNUSED_ATTR void *data) {
static void timer_config_save_cb(UNUSED_ATTR void *data) {
  btif_config_write();
}

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);
}