Loading system/bta/gatt/bta_gattc_act.cc +68 −16 Original line number Diff line number Diff line Loading @@ -808,6 +808,10 @@ void bta_gattc_start_discover_internal(tBTA_GATTC_CLCB* p_clcb) { p_clcb->disc_active = true; } static void bta_gattc_continue_with_version_and_cache_known( tBTA_GATTC_CLCB* p_clcb, RobustCachingSupport cache_support, bool is_svc_chg); /** Start a discovery on server */ void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb, UNUSED_ATTR const tBTA_GATTC_DATA* p_data) { Loading Loading @@ -839,9 +843,65 @@ void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb, p_clcb->p_srcb->srvc_hdl_chg = false; p_clcb->p_srcb->update_count = 0; p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT; p_clcb->p_srcb->disc_blocked_waiting_on_version = false; auto cache_support = GetRobustCachingSupport(p_clcb, p_clcb->p_srcb->gatt_database); if (cache_support == RobustCachingSupport::W4_REMOTE_VERSION) { LOG_INFO( "Pausing service discovery till remote version is read conn_id:%d", p_clcb->bta_conn_id); p_clcb->p_srcb->disc_blocked_waiting_on_version = true; p_clcb->p_srcb->blocked_conn_id = p_clcb->bta_conn_id; return; } bta_gattc_continue_with_version_and_cache_known(p_clcb, cache_support, is_svc_chg); } /* pending operation, wait until it finishes */ else { p_clcb->auto_update = BTA_GATTC_DISC_WAITING; if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) p_clcb->state = BTA_GATTC_CONN_ST; /* set clcb state */ } } void bta_gattc_continue_discovery_if_needed(const RawAddress& bd_addr, uint16_t acl_handle) { tBTA_GATTC_SERV* p_srcb = bta_gattc_find_srvr_cache(bd_addr); if (!p_srcb || !p_srcb->disc_blocked_waiting_on_version) { return; } uint16_t conn_id = p_srcb->blocked_conn_id; p_srcb->disc_blocked_waiting_on_version = false; p_srcb->blocked_conn_id = 0; LOG_INFO("Received remote version, continue service discovery for %s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); if (GetRobustCachingSupport(p_clcb, p_clcb->p_srcb->gatt_database) == RobustCachingSupport::UNSUPPORTED) { tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); if (!p_clcb) { LOG_ERROR("Can't find CLCB to continue service discovery, id:%d", conn_id); return; } bool is_svc_chg = p_clcb->p_srcb->srvc_hdl_chg; auto cache_support = GetRobustCachingSupport(p_clcb, p_clcb->p_srcb->gatt_database); bta_gattc_continue_with_version_and_cache_known(p_clcb, cache_support, is_svc_chg); } void bta_gattc_continue_with_version_and_cache_known( tBTA_GATTC_CLCB* p_clcb, RobustCachingSupport cache_support, bool is_svc_chg) { if (cache_support == RobustCachingSupport::UNSUPPORTED) { // Skip initial DB hash read if we have strong reason (due to interop, // or a prior discovery) to believe that it is unsupported. p_clcb->p_srcb->srvc_hdl_db_hash = false; Loading @@ -852,21 +912,13 @@ void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb, p_clcb->p_srcb->srvc_hdl_db_hash && bta_gattc_read_db_hash(p_clcb, is_svc_chg)) { LOG(INFO) << __func__ << ": pending service discovery, read db hash first"; << ": pending service discovery, read db hash first conn_id:" << loghex(p_clcb->bta_conn_id); p_clcb->p_srcb->srvc_hdl_db_hash = false; return; } bta_gattc_start_discover_internal(p_clcb); } /* pending operation, wait until it finishes */ else { p_clcb->auto_update = BTA_GATTC_DISC_WAITING; if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) p_clcb->state = BTA_GATTC_CONN_ST; /* set clcb state */ } } /** discovery on server is finished */ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb, Loading system/bta/gatt/bta_gattc_cache.cc +6 −0 Original line number Diff line number Diff line Loading @@ -164,6 +164,12 @@ RobustCachingSupport GetRobustCachingSupport(const tBTA_GATTC_CLCB* p_clcb, return RobustCachingSupport::UNSUPPORTED; } if (p_clcb->transport == BT_TRANSPORT_LE && !BTM_IsRemoteVersionReceived(p_clcb->bda)) { LOG_INFO("version info is not ready yet"); return RobustCachingSupport::W4_REMOTE_VERSION; } // This is workaround for the embedded devices being already on the market // and having a serious problem with handle Read By Type with // GATT_UUID_DATABASE_HASH. With this workaround, Android will assume that Loading system/bta/gatt/bta_gattc_int.h +4 −0 Original line number Diff line number Diff line Loading @@ -232,6 +232,9 @@ typedef struct { uint16_t attr_index; /* cahce NV saving/loading attribute index */ uint16_t mtu; bool disc_blocked_waiting_on_version; uint16_t blocked_conn_id; } tBTA_GATTC_SERV; #ifndef BTA_GATTC_NOTIF_REG_MAX Loading Loading @@ -480,6 +483,7 @@ enum class RobustCachingSupport { UNSUPPORTED, SUPPORTED, UNKNOWN, W4_REMOTE_VERSION }; RobustCachingSupport GetRobustCachingSupport(const tBTA_GATTC_CLCB* p_clcb, const gatt::Database& db); Loading system/stack/acl/acl.cc +1 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include "types/raw_address.h" void tACL_CONN::Reset() { remote_version_received = false; memset(peer_le_features, 0, sizeof(peer_le_features)); peer_le_features_valid = false; memset(peer_lmp_feature_pages, 0, sizeof(peer_lmp_feature_pages)); Loading system/stack/acl/acl.h +3 −0 Original line number Diff line number Diff line Loading @@ -180,6 +180,9 @@ struct tACL_CONN { BD_FEATURES peer_lmp_feature_pages[HCI_EXT_FEATURES_PAGE_MAX + 1]; bool peer_lmp_feature_valid[HCI_EXT_FEATURES_PAGE_MAX + 1]; /* Whether "Read Remote Version Information Complete" was received */ bool remote_version_received{false}; RawAddress active_remote_addr; tBLE_ADDR_TYPE active_remote_addr_type; Loading Loading
system/bta/gatt/bta_gattc_act.cc +68 −16 Original line number Diff line number Diff line Loading @@ -808,6 +808,10 @@ void bta_gattc_start_discover_internal(tBTA_GATTC_CLCB* p_clcb) { p_clcb->disc_active = true; } static void bta_gattc_continue_with_version_and_cache_known( tBTA_GATTC_CLCB* p_clcb, RobustCachingSupport cache_support, bool is_svc_chg); /** Start a discovery on server */ void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb, UNUSED_ATTR const tBTA_GATTC_DATA* p_data) { Loading Loading @@ -839,9 +843,65 @@ void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb, p_clcb->p_srcb->srvc_hdl_chg = false; p_clcb->p_srcb->update_count = 0; p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT; p_clcb->p_srcb->disc_blocked_waiting_on_version = false; auto cache_support = GetRobustCachingSupport(p_clcb, p_clcb->p_srcb->gatt_database); if (cache_support == RobustCachingSupport::W4_REMOTE_VERSION) { LOG_INFO( "Pausing service discovery till remote version is read conn_id:%d", p_clcb->bta_conn_id); p_clcb->p_srcb->disc_blocked_waiting_on_version = true; p_clcb->p_srcb->blocked_conn_id = p_clcb->bta_conn_id; return; } bta_gattc_continue_with_version_and_cache_known(p_clcb, cache_support, is_svc_chg); } /* pending operation, wait until it finishes */ else { p_clcb->auto_update = BTA_GATTC_DISC_WAITING; if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) p_clcb->state = BTA_GATTC_CONN_ST; /* set clcb state */ } } void bta_gattc_continue_discovery_if_needed(const RawAddress& bd_addr, uint16_t acl_handle) { tBTA_GATTC_SERV* p_srcb = bta_gattc_find_srvr_cache(bd_addr); if (!p_srcb || !p_srcb->disc_blocked_waiting_on_version) { return; } uint16_t conn_id = p_srcb->blocked_conn_id; p_srcb->disc_blocked_waiting_on_version = false; p_srcb->blocked_conn_id = 0; LOG_INFO("Received remote version, continue service discovery for %s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); if (GetRobustCachingSupport(p_clcb, p_clcb->p_srcb->gatt_database) == RobustCachingSupport::UNSUPPORTED) { tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); if (!p_clcb) { LOG_ERROR("Can't find CLCB to continue service discovery, id:%d", conn_id); return; } bool is_svc_chg = p_clcb->p_srcb->srvc_hdl_chg; auto cache_support = GetRobustCachingSupport(p_clcb, p_clcb->p_srcb->gatt_database); bta_gattc_continue_with_version_and_cache_known(p_clcb, cache_support, is_svc_chg); } void bta_gattc_continue_with_version_and_cache_known( tBTA_GATTC_CLCB* p_clcb, RobustCachingSupport cache_support, bool is_svc_chg) { if (cache_support == RobustCachingSupport::UNSUPPORTED) { // Skip initial DB hash read if we have strong reason (due to interop, // or a prior discovery) to believe that it is unsupported. p_clcb->p_srcb->srvc_hdl_db_hash = false; Loading @@ -852,21 +912,13 @@ void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb, p_clcb->p_srcb->srvc_hdl_db_hash && bta_gattc_read_db_hash(p_clcb, is_svc_chg)) { LOG(INFO) << __func__ << ": pending service discovery, read db hash first"; << ": pending service discovery, read db hash first conn_id:" << loghex(p_clcb->bta_conn_id); p_clcb->p_srcb->srvc_hdl_db_hash = false; return; } bta_gattc_start_discover_internal(p_clcb); } /* pending operation, wait until it finishes */ else { p_clcb->auto_update = BTA_GATTC_DISC_WAITING; if (p_clcb->p_srcb->state == BTA_GATTC_SERV_IDLE) p_clcb->state = BTA_GATTC_CONN_ST; /* set clcb state */ } } /** discovery on server is finished */ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb, Loading
system/bta/gatt/bta_gattc_cache.cc +6 −0 Original line number Diff line number Diff line Loading @@ -164,6 +164,12 @@ RobustCachingSupport GetRobustCachingSupport(const tBTA_GATTC_CLCB* p_clcb, return RobustCachingSupport::UNSUPPORTED; } if (p_clcb->transport == BT_TRANSPORT_LE && !BTM_IsRemoteVersionReceived(p_clcb->bda)) { LOG_INFO("version info is not ready yet"); return RobustCachingSupport::W4_REMOTE_VERSION; } // This is workaround for the embedded devices being already on the market // and having a serious problem with handle Read By Type with // GATT_UUID_DATABASE_HASH. With this workaround, Android will assume that Loading
system/bta/gatt/bta_gattc_int.h +4 −0 Original line number Diff line number Diff line Loading @@ -232,6 +232,9 @@ typedef struct { uint16_t attr_index; /* cahce NV saving/loading attribute index */ uint16_t mtu; bool disc_blocked_waiting_on_version; uint16_t blocked_conn_id; } tBTA_GATTC_SERV; #ifndef BTA_GATTC_NOTIF_REG_MAX Loading Loading @@ -480,6 +483,7 @@ enum class RobustCachingSupport { UNSUPPORTED, SUPPORTED, UNKNOWN, W4_REMOTE_VERSION }; RobustCachingSupport GetRobustCachingSupport(const tBTA_GATTC_CLCB* p_clcb, const gatt::Database& db); Loading
system/stack/acl/acl.cc +1 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include "types/raw_address.h" void tACL_CONN::Reset() { remote_version_received = false; memset(peer_le_features, 0, sizeof(peer_le_features)); peer_le_features_valid = false; memset(peer_lmp_feature_pages, 0, sizeof(peer_lmp_feature_pages)); Loading
system/stack/acl/acl.h +3 −0 Original line number Diff line number Diff line Loading @@ -180,6 +180,9 @@ struct tACL_CONN { BD_FEATURES peer_lmp_feature_pages[HCI_EXT_FEATURES_PAGE_MAX + 1]; bool peer_lmp_feature_valid[HCI_EXT_FEATURES_PAGE_MAX + 1]; /* Whether "Read Remote Version Information Complete" was received */ bool remote_version_received{false}; RawAddress active_remote_addr; tBLE_ADDR_TYPE active_remote_addr_type; Loading