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

Commit 5b242b54 authored by Jakub Pawłowski's avatar Jakub Pawłowski Committed by Automerger Merge Worker
Browse files

Merge changes I991994e9,I46512626,Ib23570d8 am: 1bb3c35f am: 2dd0d59b

parents c83dbcb4 2dd0d59b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ cc_library_static {
        "gatt/bta_gattc_act.cc",
        "gatt/bta_gattc_api.cc",
        "gatt/bta_gattc_cache.cc",
        "gatt/bta_gattc_db_storage.cc",
        "gatt/bta_gattc_main.cc",
        "gatt/bta_gattc_queue.cc",
        "gatt/bta_gattc_utils.cc",
@@ -233,6 +234,7 @@ cc_test {
        "gatt/bta_gattc_act.cc",
        "gatt/bta_gattc_api.cc",
        "gatt/bta_gattc_cache.cc",
        "gatt/bta_gattc_db_storage.cc",
        "gatt/bta_gattc_main.cc",
        "gatt/bta_gattc_queue.cc",
        "gatt/bta_gattc_utils.cc",
+7 −2
Original line number Diff line number Diff line
@@ -501,7 +501,9 @@ void bta_gattc_conn(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) {
      p_clcb->p_srcb->state != BTA_GATTC_SERV_IDLE) {
    if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) {
      p_clcb->p_srcb->state = BTA_GATTC_SERV_LOAD;
      if (bta_gattc_cache_load(p_clcb->p_srcb)) {
      gatt::Database db = bta_gattc_cache_load(p_clcb->p_srcb->server_bda);
      if (!db.IsEmpty()) {
        p_clcb->p_srcb->gatt_database = db;
        p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
        bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_SUCCESS);
      } else {
@@ -1201,7 +1203,10 @@ static bool bta_gattc_process_srvc_chg_ind(uint16_t conn_id,
  Uuid srvc_chg_uuid = Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD);

  if (p_srcb->gatt_database.IsEmpty() && p_srcb->state == BTA_GATTC_SERV_IDLE) {
    bta_gattc_cache_load(p_srcb);
    gatt::Database db = bta_gattc_cache_load(p_srcb->server_bda);
    if (!db.IsEmpty()) {
      p_srcb->gatt_database = db;
    }
  }

  const gatt::Characteristic* p_char =
+1 −139
Original line number Diff line number Diff line
@@ -50,10 +50,7 @@ using gatt::DatabaseBuilder;
using gatt::Descriptor;
using gatt::IncludedService;
using gatt::Service;
using gatt::StoredAttribute;

static void bta_gattc_cache_write(const RawAddress& server_bda,
                                  const std::vector<StoredAttribute>& attr);
static tGATT_STATUS bta_gattc_sdp_service_disc(uint16_t conn_id,
                                               tBTA_GATTC_SERV* p_server_cb);
const Descriptor* bta_gattc_get_descriptor_srcb(tBTA_GATTC_SERV* p_srcb,
@@ -74,16 +71,6 @@ static void bta_gattc_read_ext_prop_desc_cmpl(tBTA_GATTC_CLCB* p_clcb,

#define BTA_GATT_SDP_DB_SIZE 4096

#define GATT_CACHE_PREFIX "/data/misc/bluetooth/gatt_cache_"
#define GATT_CACHE_VERSION 6

static void bta_gattc_generate_cache_file_name(char* buffer, size_t buffer_len,
                                               const RawAddress& bda) {
  snprintf(buffer, buffer_len, "%s%02x%02x%02x%02x%02x%02x", GATT_CACHE_PREFIX,
           bda.address[0], bda.address[1], bda.address[2], bda.address[3],
           bda.address[4], bda.address[5]);
}

/*****************************************************************************
 *  Constants and data types
 ****************************************************************************/
@@ -231,7 +218,7 @@ static void bta_gattc_explore_srvc_finished(uint16_t conn_id,

  if (btm_sec_is_a_bonded_dev(p_srvc_cb->server_bda)) {
    bta_gattc_cache_write(p_clcb->p_srcb->server_bda,
                          p_clcb->p_srcb->gatt_database.Serialize());
                          p_clcb->p_srcb->gatt_database);
  }

  // After success, reset the count.
@@ -922,128 +909,3 @@ void bta_gattc_get_gatt_db(uint16_t conn_id, uint16_t start_handle,
  bta_gattc_get_gatt_db_impl(p_clcb->p_srcb, start_handle, end_handle, db,
                             count);
}

/*******************************************************************************
 *
 * Function         bta_gattc_cache_load
 *
 * Description      Load GATT cache from storage for server.
 *
 * Parameter        p_srcb: pointer to server cache, that will
 *                          be filled from storage
 * Returns          true on success, false otherwise
 *
 ******************************************************************************/
bool bta_gattc_cache_load(tBTA_GATTC_SERV* p_srcb) {
  char fname[255] = {0};
  bta_gattc_generate_cache_file_name(fname, sizeof(fname), p_srcb->server_bda);

  FILE* fd = fopen(fname, "rb");
  if (!fd) {
    LOG(ERROR) << __func__ << ": can't open GATT cache file " << fname
               << " for reading, error: " << strerror(errno);
    return false;
  }

  uint16_t cache_ver = 0;
  bool success = false;
  uint16_t num_attr = 0;

  if (fread(&cache_ver, sizeof(uint16_t), 1, fd) != 1) {
    LOG(ERROR) << __func__ << ": can't read GATT cache version from: " << fname;
    goto done;
  }

  if (cache_ver != GATT_CACHE_VERSION) {
    LOG(ERROR) << __func__ << ": wrong GATT cache version: " << fname;
    goto done;
  }

  if (fread(&num_attr, sizeof(uint16_t), 1, fd) != 1) {
    LOG(ERROR) << __func__
               << ": can't read number of GATT attributes: " << fname;
    goto done;
  }

  {
    std::vector<StoredAttribute> attr(num_attr);

    if (fread(attr.data(), sizeof(StoredAttribute), num_attr, fd) != num_attr) {
      LOG(ERROR) << __func__ << "s: can't read GATT attributes: " << fname;
      goto done;
    }

    p_srcb->gatt_database = gatt::Database::Deserialize(attr, &success);
  }

done:
  fclose(fd);
  return success;
}

/*******************************************************************************
 *
 * Function         bta_gattc_cache_write
 *
 * Description      This callout function is executed by GATT when a server
 *                  cache is available to save.
 *
 * Parameter        server_bda: server bd address of this cache belongs to
 *                  attr: attributes to save.
 * Returns
 *
 ******************************************************************************/
static void bta_gattc_cache_write(const RawAddress& server_bda,
                                  const std::vector<StoredAttribute>& attr) {
  char fname[255] = {0};
  bta_gattc_generate_cache_file_name(fname, sizeof(fname), server_bda);

  FILE* fd = fopen(fname, "wb");
  if (!fd) {
    LOG(ERROR) << __func__
               << ": can't open GATT cache file for writing: " << fname;
    return;
  }

  uint16_t cache_ver = GATT_CACHE_VERSION;
  if (fwrite(&cache_ver, sizeof(uint16_t), 1, fd) != 1) {
    LOG(ERROR) << __func__ << ": can't write GATT cache version: " << fname;
    fclose(fd);
    return;
  }

  uint16_t num_attr = attr.size();
  if (fwrite(&num_attr, sizeof(uint16_t), 1, fd) != 1) {
    LOG(ERROR) << __func__
               << ": can't write GATT cache attribute count: " << fname;
    fclose(fd);
    return;
  }

  if (fwrite(attr.data(), sizeof(StoredAttribute), num_attr, fd) != num_attr) {
    LOG(ERROR) << __func__ << ": can't write GATT cache attributes: " << fname;
    fclose(fd);
    return;
  }

  fclose(fd);
}

/*******************************************************************************
 *
 * Function         bta_gattc_cache_reset
 *
 * Description      This callout function is executed by GATTC to reset cache in
 *                  application
 *
 * Parameter        server_bda: server bd address of this cache belongs to
 *
 * Returns          void.
 *
 ******************************************************************************/
void bta_gattc_cache_reset(const RawAddress& server_bda) {
  VLOG(1) << __func__;
  char fname[255] = {0};
  bta_gattc_generate_cache_file_name(fname, sizeof(fname), server_bda);
  unlink(fname);
}
+192 −0
Original line number Diff line number Diff line
/******************************************************************************
 *
 *  Copyright 2022 The Android Open Source Project
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

#include "bta/gatt/bta_gattc_int.h"

using gatt::StoredAttribute;

#define GATT_CACHE_PREFIX "/data/misc/bluetooth/gatt_cache_"
#define GATT_CACHE_VERSION 6

static void bta_gattc_generate_cache_file_name(char* buffer, size_t buffer_len,
                                               const RawAddress& bda) {
  snprintf(buffer, buffer_len, "%s%02x%02x%02x%02x%02x%02x", GATT_CACHE_PREFIX,
           bda.address[0], bda.address[1], bda.address[2], bda.address[3],
           bda.address[4], bda.address[5]);
}

static gatt::Database EMPTY_DB;

/*******************************************************************************
 *
 * Function         bta_gattc_load_db
 *
 * Description      Load GATT database from storage.
 *
 * Parameter        fname: input file name
 *
 * Returns          non-empty GATT database on success, empty GATT database
 *                  otherwise
 *
 ******************************************************************************/
static gatt::Database bta_gattc_load_db(const char* fname) {
  FILE* fd = fopen(fname, "rb");
  if (!fd) {
    LOG(ERROR) << __func__ << ": can't open GATT cache file " << fname
               << " for reading, error: " << strerror(errno);
    return EMPTY_DB;
  }

  uint16_t cache_ver = 0;
  uint16_t num_attr = 0;

  if (fread(&cache_ver, sizeof(uint16_t), 1, fd) != 1) {
    LOG(ERROR) << __func__ << ": can't read GATT cache version from: " << fname;
    goto done;
  }

  if (cache_ver != GATT_CACHE_VERSION) {
    LOG(ERROR) << __func__ << ": wrong GATT cache version: " << fname;
    goto done;
  }

  if (fread(&num_attr, sizeof(uint16_t), 1, fd) != 1) {
    LOG(ERROR) << __func__
               << ": can't read number of GATT attributes: " << fname;
    goto done;
  }

  {
    std::vector<StoredAttribute> attr(num_attr);

    if (fread(attr.data(), sizeof(StoredAttribute), num_attr, fd) != num_attr) {
      LOG(ERROR) << __func__ << ": can't read GATT attributes: " << fname;
      goto done;
    }

    bool success = false;
    gatt::Database result = gatt::Database::Deserialize(attr, &success);
    return success ? result : EMPTY_DB;
  }

done:
  fclose(fd);
  return EMPTY_DB;
}

/*******************************************************************************
 *
 * Function         bta_gattc_cache_load
 *
 * Description      Load GATT cache from storage for server.
 *
 * Parameter        bd_address: remote device address
 *
 * Returns          non-empty GATT database on success, empty GATT database
 *                  otherwise
 *
 ******************************************************************************/
gatt::Database bta_gattc_cache_load(const RawAddress& server_bda) {
  char fname[255] = {0};
  bta_gattc_generate_cache_file_name(fname, sizeof(fname), server_bda);
  return bta_gattc_load_db(fname);
}

/*******************************************************************************
 *
 * Function         bta_gattc_store_db
 *
 * Description      Storess GATT db.
 *
 * Parameter        fname: output file name
 *                  attr: attributes to save.
 *
 * Returns          true on success, false otherwise
 *
 ******************************************************************************/
static bool bta_gattc_store_db(const char* fname,
                               const std::vector<StoredAttribute>& attr) {
  FILE* fd = fopen(fname, "wb");
  if (!fd) {
    LOG(ERROR) << __func__
               << ": can't open GATT cache file for writing: " << fname;
    return false;
  }

  uint16_t cache_ver = GATT_CACHE_VERSION;
  if (fwrite(&cache_ver, sizeof(uint16_t), 1, fd) != 1) {
    LOG(ERROR) << __func__ << ": can't write GATT cache version: " << fname;
    fclose(fd);
    return false;
  }

  uint16_t num_attr = attr.size();
  if (fwrite(&num_attr, sizeof(uint16_t), 1, fd) != 1) {
    LOG(ERROR) << __func__
               << ": can't write GATT cache attribute count: " << fname;
    fclose(fd);
    return false;
  }

  if (fwrite(attr.data(), sizeof(StoredAttribute), num_attr, fd) != num_attr) {
    LOG(ERROR) << __func__ << ": can't write GATT cache attributes: " << fname;
    fclose(fd);
    return false;
  }

  fclose(fd);
  return true;
}

/*******************************************************************************
 *
 * Function         bta_gattc_cache_write
 *
 * Description      This callout function is executed by GATT when a server
 *                  cache is available to save.
 *
 * Parameter        server_bda: server bd address of this cache belongs to
 *                  database: attributes to save.
 * Returns
 *
 ******************************************************************************/
void bta_gattc_cache_write(const RawAddress& server_bda,
                           const gatt::Database& database) {
  char fname[255] = {0};
  bta_gattc_generate_cache_file_name(fname, sizeof(fname), server_bda);
  bta_gattc_store_db(fname, database.Serialize());
}

/*******************************************************************************
 *
 * Function         bta_gattc_cache_reset
 *
 * Description      This callout function is executed by GATTC to reset cache in
 *                  application
 *
 * Parameter        server_bda: server bd address of this cache belongs to
 *
 * Returns          void.
 *
 ******************************************************************************/
void bta_gattc_cache_reset(const RawAddress& server_bda) {
  VLOG(1) << __func__;
  char fname[255] = {0};
  bta_gattc_generate_cache_file_name(fname, sizeof(fname), server_bda);
  unlink(fname);
}
+3 −1
Original line number Diff line number Diff line
@@ -476,7 +476,9 @@ extern tBTA_GATTC_CONN* bta_gattc_conn_find(const RawAddress& remote_bda);
extern tBTA_GATTC_CONN* bta_gattc_conn_find_alloc(const RawAddress& remote_bda);
extern bool bta_gattc_conn_dealloc(const RawAddress& remote_bda);

extern bool bta_gattc_cache_load(tBTA_GATTC_SERV* p_srcb);
extern gatt::Database bta_gattc_cache_load(const RawAddress& server_bda);
extern void bta_gattc_cache_write(const RawAddress& server_bda,
                                  const gatt::Database& database);
extern void bta_gattc_cache_reset(const RawAddress& server_bda);

extern bool bta_gattc_read_db_hash(tBTA_GATTC_CLCB* p_clcb);