Loading system/btif/include/btif_storage.h +6 −0 Original line number Diff line number Diff line Loading @@ -242,6 +242,12 @@ uint8_t btif_storage_get_gatt_cl_supp_feat(const RawAddress& bd_addr); /** Remove client supported features */ void btif_storage_remove_gatt_cl_supp_feat(const RawAddress& bd_addr); /** Stores information about GATT server supported features */ void btif_storage_set_gatt_sr_supp_feat(const RawAddress& addr, uint8_t feat); /** Gets information about GATT server supported features */ uint8_t btif_storage_get_sr_supp_feat(const RawAddress& bd_addr); /** Store last server database hash for remote client */ void btif_storage_set_gatt_cl_db_hash(const RawAddress& bd_addr, Octet16 hash); Loading system/btif/src/btif_storage.cc +32 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ using bluetooth::Uuid; #define BTIF_STORAGE_KEY_ADAPTER_DISC_TIMEOUT "DiscoveryTimeout" #define BTIF_STORAGE_KEY_GATT_CLIENT_SUPPORTED "GattClientSupportedFeatures" #define BTIF_STORAGE_KEY_GATT_CLIENT_DB_HASH "GattClientDatabaseHash" #define BTIF_STORAGE_KEY_GATT_SERVER_SUPPORTED "GattServerSupportedFeatures" /* This is a local property to add a device found */ #define BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP 0xFF Loading Loading @@ -855,6 +856,9 @@ bt_status_t btif_storage_remove_bonded_device( if (btif_config_exist(bdstr, BTIF_STORAGE_KEY_GATT_CLIENT_DB_HASH)) { ret &= btif_config_remove(bdstr, BTIF_STORAGE_KEY_GATT_CLIENT_DB_HASH); } if (btif_config_exist(bdstr, BTIF_STORAGE_KEY_GATT_SERVER_SUPPORTED)) { ret &= btif_config_remove(bdstr, BTIF_STORAGE_KEY_GATT_SERVER_SUPPORTED); } /* write bonded info immediately */ btif_config_flush(); Loading Loading @@ -1660,6 +1664,34 @@ bool btif_storage_get_hearing_aid_prop( return true; } /** Stores information about GATT server supported features */ void btif_storage_set_gatt_sr_supp_feat(const RawAddress& addr, uint8_t feat) { do_in_jni_thread( FROM_HERE, Bind( [](const RawAddress& addr, uint8_t feat) { std::string bdstr = addr.ToString(); VLOG(2) << "GATT server supported features for: " << bdstr << " features: " << +feat; btif_config_set_int( bdstr, BTIF_STORAGE_KEY_GATT_SERVER_SUPPORTED, feat); btif_config_save(); }, addr, feat)); } /** Gets information about GATT server supported features */ uint8_t btif_storage_get_sr_supp_feat(const RawAddress& bd_addr) { auto name = bd_addr.ToString(); int value = 0; btif_config_get_int(name, BTIF_STORAGE_KEY_GATT_SERVER_SUPPORTED, &value); BTIF_TRACE_DEBUG("Remote device: %s GATT server supported features 0x%02x", name.c_str(), value); return value; } /******************************************************************************* * * Function btif_storage_is_restricted_device Loading system/stack/eatt/eatt_impl.h +44 −20 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ namespace bluetooth { namespace eatt { #define BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK 0x01 class eatt_device { public: RawAddress bda_; Loading Loading @@ -129,6 +131,12 @@ struct eatt_impl { &local_coc_cfg)) return; if (!eatt_dev->eatt_tcb_) { eatt_dev->eatt_tcb_ = gatt_find_tcb_by_addr(eatt_dev->bda_, BT_TRANSPORT_LE); CHECK(eatt_dev->eatt_tcb_); } for (uint16_t cid : lcids) { EattChannel* channel = find_eatt_channel_by_cid(bda, cid); CHECK(!channel); Loading @@ -138,8 +146,6 @@ struct eatt_impl { eatt_dev->eatt_channels.insert({cid, chan}); chan->EattChannelSetState(EattChannelState::EATT_CHANNEL_OPENED); CHECK(eatt_dev->eatt_tcb_); eatt_dev->eatt_tcb_->eatt++; LOG(INFO) << __func__ << " Channel connected CID " << loghex(cid); Loading Loading @@ -269,9 +275,7 @@ struct eatt_impl { } bool is_eatt_supported_by_peer(const RawAddress& bd_addr) { /* For now on the list we have only devices which does support eatt */ eatt_device* eatt_dev = find_device_by_address(bd_addr); return eatt_dev ? true : false; return gatt_profile_get_eatt_support(bd_addr); } eatt_device* find_device_by_address(const RawAddress& bd_addr) { Loading Loading @@ -313,7 +317,7 @@ struct eatt_impl { << +connecting_cids.size(); for (uint16_t cid : connecting_cids) { LOG(INFO) << " /n/t cid: " << loghex(cid); LOG(INFO) << " \t cid: " << loghex(cid); auto chan = std::make_shared<EattChannel>(eatt_dev->bda_, cid, 0, eatt_dev->rx_mtu_); Loading Loading @@ -567,12 +571,24 @@ struct eatt_impl { << bd_addr; } void eatt_is_supported_cb(const RawAddress& bd_addr, bool is_eatt_supported) { void supported_features_cb(uint8_t role, const RawAddress& bd_addr, uint8_t features) { bool is_eatt_supported = features & BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK; LOG(INFO) << __func__ << " " << bd_addr << " is_eatt_supported = " << int(is_eatt_supported); if (!is_eatt_supported) return; eatt_device* eatt_dev = add_eatt_device(bd_addr); if (role != HCI_ROLE_CENTRAL) { /* TODO For now do nothing, we could run a timer here and start EATT if * not started by central */ LOG(INFO) << " EATT Should be connected by the central. Let's wait for it."; return; } connect_eatt(eatt_dev); } Loading @@ -582,7 +598,16 @@ struct eatt_impl { LOG(INFO) << __func__ << " " << bd_addr; eatt_device* eatt_dev = find_device_by_address(bd_addr); if (!eatt_dev) return; if (!eatt_dev) { LOG(WARNING) << __func__ << " no eatt device found"; return; } if (!eatt_dev->eatt_tcb_) { LOG_ASSERT(eatt_dev->eatt_channels.size() == 0); LOG(WARNING) << __func__ << " no eatt channels found"; return; } auto iter = eatt_dev->eatt_channels.begin(); while (iter != eatt_dev->eatt_channels.end()) { Loading @@ -609,27 +634,26 @@ struct eatt_impl { LOG(INFO) << __func__ << " device " << bd_addr << " role" << (role == HCI_ROLE_CENTRAL ? "central" : "peripheral"); if (eatt_dev) { /* We are reconnecting device we know that support EATT. * Just connect CoC */ LOG(INFO) << __func__ << " Known device, connect eCoC"; if (role != HCI_ROLE_CENTRAL) { /* TODO For now do nothing, we could run a timer here and start EATT if * not started by central */ LOG(INFO) << " EATT Should be connected by the central. Let's wait for it."; return; } if (eatt_dev) { /* We are reconnecting device we know that support EATT. * Just connect CoC */ LOG(INFO) << __func__ << " Known device, connect eCoC"; connect_eatt(eatt_dev); return; } /* For new device, first check if EATT is supported. */ if (gatt_profile_get_eatt_support( bd_addr, base::BindOnce(&eatt_impl::eatt_is_supported_cb, base::Unretained(this))) == false) { /* For new device, first read GATT server supported features. */ if (gatt_cl_read_sr_supp_feat_req( bd_addr, base::BindOnce(&eatt_impl::supported_features_cb, base::Unretained(this), role)) == false) { LOG(INFO) << __func__ << "Eatt is not supported. Checked for device " << bd_addr; } Loading system/stack/gatt/gatt_attr.cc +52 −37 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include "bt_target.h" #include "bt_utils.h" #include "btif/include/btif_storage.h" #include "eatt/eatt.h" #include "gatt_api.h" #include "gatt_int.h" #include "gd/common/init_flags.h" Loading @@ -47,11 +48,12 @@ using bluetooth::Uuid; #define BLE_GATT_CL_ANDROID_SUP_FEAT \ (BLE_GATT_CL_SUP_FEAT_EATT_BITMASK | BLE_GATT_CL_SUP_FEAT_MULTI_NOTIF_BITMASK) using gatt_eatt_support_cb = base::OnceCallback<void(const RawAddress&, bool)>; using gatt_sr_supported_feat_cb = base::OnceCallback<void(const RawAddress&, uint8_t)>; typedef struct { uint16_t op_uuid; gatt_eatt_support_cb cb; gatt_sr_supported_feat_cb cb; } gatt_op_cb_data; static std::map<uint16_t, gatt_op_cb_data> OngoingOps; Loading Loading @@ -502,19 +504,6 @@ static void gatt_disc_cmpl_cback(uint16_t conn_id, tGATT_DISC_TYPE disc_type, gatt_cl_start_config_ccc(p_clcb); } static void gatt_attr_send_is_eatt_cb(uint16_t conn_id, gatt_op_cb_data* cb, bool eatt_supported) { tGATT_IF gatt_if; RawAddress bd_addr; tBT_TRANSPORT transport; GATT_GetConnectionInfor(conn_id, &gatt_if, bd_addr, &transport); std::move(cb->cb).Run(bd_addr, eatt_supported); cb->op_uuid = 0; } static bool gatt_svc_read_cl_supp_feat_req(uint16_t conn_id, gatt_op_cb_data* cb) { tGATT_READ_PARAM param; Loading Loading @@ -585,6 +574,7 @@ static void gatt_cl_op_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op, gatt_op_cb_data* operation_callback_data = &iter->second; uint16_t cl_op_uuid = operation_callback_data->op_uuid; operation_callback_data->op_uuid = 0; uint8_t* pp = p_data->att_value.value; Loading @@ -592,24 +582,24 @@ static void gatt_cl_op_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op, switch (cl_op_uuid) { case GATT_UUID_SERVER_SUP_FEAT: { uint8_t supported_feat_mask = 0; uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); tGATT_TCB& tcb = gatt_cb.tcb[tcb_idx]; /* Check if EATT is supported */ if (status == GATT_SUCCESS) { STREAM_TO_UINT8(supported_feat_mask, pp); STREAM_TO_UINT8(tcb.sr_supp_feat, pp); btif_storage_set_gatt_sr_supp_feat(tcb.peer_bda, tcb.sr_supp_feat); } /* Notify user if eatt is supported */ bool eatt_supported = supported_feat_mask & BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK; gatt_attr_send_is_eatt_cb(conn_id, operation_callback_data, eatt_supported); /* Notify user about the supported features */ std::move(operation_callback_data->cb) .Run(tcb.peer_bda, tcb.sr_supp_feat); /* If server supports EATT lets try to find handle for the * client supported features characteristic, where we could write * our supported features as a client. */ if (eatt_supported) { if (tcb.sr_supp_feat & BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK) { /* If read succeed, return here */ if (gatt_svc_read_cl_supp_feat_req(conn_id, operation_callback_data)) return; Loading Loading @@ -717,19 +707,46 @@ void GATT_ConfigServiceChangeCCC(const RawAddress& remote_bda, bool enable, /******************************************************************************* * * Function gatt_svc_read_supp_feat_req * Function gatt_cl_init_sr_status * * Description Restore status for trusted GATT Server device * * Returns none * ******************************************************************************/ void gatt_cl_init_sr_status(tGATT_TCB& tcb) { tcb.sr_supp_feat = btif_storage_get_sr_supp_feat(tcb.peer_bda); if (tcb.sr_supp_feat & BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK) bluetooth::eatt::EattExtension::AddFromStorage(tcb.peer_bda); } /******************************************************************************* * * Function gatt_cl_read_sr_supp_feat_req * * Description Read remote device supported GATT feature mask. * * Returns bool * ******************************************************************************/ static bool gatt_svc_read_supp_feat_req( const RawAddress& peer_bda, uint16_t conn_id, base::OnceCallback<void(const RawAddress&, bool)> cb) { bool gatt_cl_read_sr_supp_feat_req( const RawAddress& peer_bda, base::OnceCallback<void(const RawAddress&, uint8_t)> cb) { tGATT_PROFILE_CLCB* p_clcb; tGATT_READ_PARAM param; tGATT_PROFILE_CLCB* p_clcb = gatt_profile_find_clcb_by_conn_id(conn_id); uint16_t conn_id; if (!cb) return false; VLOG(1) << __func__ << " BDA: " << peer_bda << " read gatt supported features"; GATT_GetConnIdIfConnected(gatt_cb.gatt_if, peer_bda, &conn_id, BT_TRANSPORT_LE); if (conn_id == GATT_INVALID_CONN_ID) return false; p_clcb = gatt_profile_find_clcb_by_conn_id(conn_id); if (!p_clcb) { p_clcb = gatt_profile_clcb_alloc(conn_id, peer_bda, BT_TRANSPORT_LE); } Loading Loading @@ -773,18 +790,13 @@ static bool gatt_svc_read_supp_feat_req( * * Description Check if EATT is supported with remote device. * * Returns false in case read could not be sent. * Returns if EATT is supported. * ******************************************************************************/ bool gatt_profile_get_eatt_support( const RawAddress& remote_bda, base::OnceCallback<void(const RawAddress&, bool)> cb) { bool gatt_profile_get_eatt_support(const RawAddress& remote_bda) { uint16_t conn_id; if (!cb) return false; VLOG(1) << __func__ << " BDA: " << remote_bda << " read gatt supported features"; VLOG(1) << __func__ << " BDA: " << remote_bda << " read GATT support"; GATT_GetConnIdIfConnected(gatt_cb.gatt_if, remote_bda, &conn_id, BT_TRANSPORT_LE); Loading @@ -792,7 +804,10 @@ bool gatt_profile_get_eatt_support( /* This read is important only when connected */ if (conn_id == GATT_INVALID_CONN_ID) return false; return gatt_svc_read_supp_feat_req(remote_bda, conn_id, std::move(cb)); /* Get tcb info */ uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); tGATT_TCB& tcb = gatt_cb.tcb[tcb_idx]; return tcb.sr_supp_feat & BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK; } /******************************************************************************* Loading system/stack/gatt/gatt_int.h +7 −3 Original line number Diff line number Diff line Loading @@ -317,6 +317,8 @@ typedef struct { // TODO(hylo): support byte array data /* Client supported feature*/ uint8_t cl_supp_feat; /* Server supported features */ uint8_t sr_supp_feat; /* Use for server. if false, should handle database out of sync. */ bool is_robust_cache_change_aware; Loading Loading @@ -459,9 +461,11 @@ extern void gatt_add_a_bonded_dev_for_srv_chg(const RawAddress& bda); /* from gatt_attr.cc */ extern uint16_t gatt_profile_find_conn_id_by_bd_addr(const RawAddress& bda); extern bool gatt_profile_get_eatt_support( const RawAddress& remote_bda, base::OnceCallback<void(const RawAddress&, bool)> cb); extern bool gatt_profile_get_eatt_support(const RawAddress& remote_bda); extern void gatt_cl_init_sr_status(tGATT_TCB& tcb); extern bool gatt_cl_read_sr_supp_feat_req( const RawAddress& peer_bda, base::OnceCallback<void(const RawAddress&, uint8_t)> cb); extern bool gatt_sr_is_cl_change_aware(tGATT_TCB& tcb); extern void gatt_sr_init_cl_status(tGATT_TCB& tcb); Loading Loading
system/btif/include/btif_storage.h +6 −0 Original line number Diff line number Diff line Loading @@ -242,6 +242,12 @@ uint8_t btif_storage_get_gatt_cl_supp_feat(const RawAddress& bd_addr); /** Remove client supported features */ void btif_storage_remove_gatt_cl_supp_feat(const RawAddress& bd_addr); /** Stores information about GATT server supported features */ void btif_storage_set_gatt_sr_supp_feat(const RawAddress& addr, uint8_t feat); /** Gets information about GATT server supported features */ uint8_t btif_storage_get_sr_supp_feat(const RawAddress& bd_addr); /** Store last server database hash for remote client */ void btif_storage_set_gatt_cl_db_hash(const RawAddress& bd_addr, Octet16 hash); Loading
system/btif/src/btif_storage.cc +32 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ using bluetooth::Uuid; #define BTIF_STORAGE_KEY_ADAPTER_DISC_TIMEOUT "DiscoveryTimeout" #define BTIF_STORAGE_KEY_GATT_CLIENT_SUPPORTED "GattClientSupportedFeatures" #define BTIF_STORAGE_KEY_GATT_CLIENT_DB_HASH "GattClientDatabaseHash" #define BTIF_STORAGE_KEY_GATT_SERVER_SUPPORTED "GattServerSupportedFeatures" /* This is a local property to add a device found */ #define BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP 0xFF Loading Loading @@ -855,6 +856,9 @@ bt_status_t btif_storage_remove_bonded_device( if (btif_config_exist(bdstr, BTIF_STORAGE_KEY_GATT_CLIENT_DB_HASH)) { ret &= btif_config_remove(bdstr, BTIF_STORAGE_KEY_GATT_CLIENT_DB_HASH); } if (btif_config_exist(bdstr, BTIF_STORAGE_KEY_GATT_SERVER_SUPPORTED)) { ret &= btif_config_remove(bdstr, BTIF_STORAGE_KEY_GATT_SERVER_SUPPORTED); } /* write bonded info immediately */ btif_config_flush(); Loading Loading @@ -1660,6 +1664,34 @@ bool btif_storage_get_hearing_aid_prop( return true; } /** Stores information about GATT server supported features */ void btif_storage_set_gatt_sr_supp_feat(const RawAddress& addr, uint8_t feat) { do_in_jni_thread( FROM_HERE, Bind( [](const RawAddress& addr, uint8_t feat) { std::string bdstr = addr.ToString(); VLOG(2) << "GATT server supported features for: " << bdstr << " features: " << +feat; btif_config_set_int( bdstr, BTIF_STORAGE_KEY_GATT_SERVER_SUPPORTED, feat); btif_config_save(); }, addr, feat)); } /** Gets information about GATT server supported features */ uint8_t btif_storage_get_sr_supp_feat(const RawAddress& bd_addr) { auto name = bd_addr.ToString(); int value = 0; btif_config_get_int(name, BTIF_STORAGE_KEY_GATT_SERVER_SUPPORTED, &value); BTIF_TRACE_DEBUG("Remote device: %s GATT server supported features 0x%02x", name.c_str(), value); return value; } /******************************************************************************* * * Function btif_storage_is_restricted_device Loading
system/stack/eatt/eatt_impl.h +44 −20 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ namespace bluetooth { namespace eatt { #define BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK 0x01 class eatt_device { public: RawAddress bda_; Loading Loading @@ -129,6 +131,12 @@ struct eatt_impl { &local_coc_cfg)) return; if (!eatt_dev->eatt_tcb_) { eatt_dev->eatt_tcb_ = gatt_find_tcb_by_addr(eatt_dev->bda_, BT_TRANSPORT_LE); CHECK(eatt_dev->eatt_tcb_); } for (uint16_t cid : lcids) { EattChannel* channel = find_eatt_channel_by_cid(bda, cid); CHECK(!channel); Loading @@ -138,8 +146,6 @@ struct eatt_impl { eatt_dev->eatt_channels.insert({cid, chan}); chan->EattChannelSetState(EattChannelState::EATT_CHANNEL_OPENED); CHECK(eatt_dev->eatt_tcb_); eatt_dev->eatt_tcb_->eatt++; LOG(INFO) << __func__ << " Channel connected CID " << loghex(cid); Loading Loading @@ -269,9 +275,7 @@ struct eatt_impl { } bool is_eatt_supported_by_peer(const RawAddress& bd_addr) { /* For now on the list we have only devices which does support eatt */ eatt_device* eatt_dev = find_device_by_address(bd_addr); return eatt_dev ? true : false; return gatt_profile_get_eatt_support(bd_addr); } eatt_device* find_device_by_address(const RawAddress& bd_addr) { Loading Loading @@ -313,7 +317,7 @@ struct eatt_impl { << +connecting_cids.size(); for (uint16_t cid : connecting_cids) { LOG(INFO) << " /n/t cid: " << loghex(cid); LOG(INFO) << " \t cid: " << loghex(cid); auto chan = std::make_shared<EattChannel>(eatt_dev->bda_, cid, 0, eatt_dev->rx_mtu_); Loading Loading @@ -567,12 +571,24 @@ struct eatt_impl { << bd_addr; } void eatt_is_supported_cb(const RawAddress& bd_addr, bool is_eatt_supported) { void supported_features_cb(uint8_t role, const RawAddress& bd_addr, uint8_t features) { bool is_eatt_supported = features & BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK; LOG(INFO) << __func__ << " " << bd_addr << " is_eatt_supported = " << int(is_eatt_supported); if (!is_eatt_supported) return; eatt_device* eatt_dev = add_eatt_device(bd_addr); if (role != HCI_ROLE_CENTRAL) { /* TODO For now do nothing, we could run a timer here and start EATT if * not started by central */ LOG(INFO) << " EATT Should be connected by the central. Let's wait for it."; return; } connect_eatt(eatt_dev); } Loading @@ -582,7 +598,16 @@ struct eatt_impl { LOG(INFO) << __func__ << " " << bd_addr; eatt_device* eatt_dev = find_device_by_address(bd_addr); if (!eatt_dev) return; if (!eatt_dev) { LOG(WARNING) << __func__ << " no eatt device found"; return; } if (!eatt_dev->eatt_tcb_) { LOG_ASSERT(eatt_dev->eatt_channels.size() == 0); LOG(WARNING) << __func__ << " no eatt channels found"; return; } auto iter = eatt_dev->eatt_channels.begin(); while (iter != eatt_dev->eatt_channels.end()) { Loading @@ -609,27 +634,26 @@ struct eatt_impl { LOG(INFO) << __func__ << " device " << bd_addr << " role" << (role == HCI_ROLE_CENTRAL ? "central" : "peripheral"); if (eatt_dev) { /* We are reconnecting device we know that support EATT. * Just connect CoC */ LOG(INFO) << __func__ << " Known device, connect eCoC"; if (role != HCI_ROLE_CENTRAL) { /* TODO For now do nothing, we could run a timer here and start EATT if * not started by central */ LOG(INFO) << " EATT Should be connected by the central. Let's wait for it."; return; } if (eatt_dev) { /* We are reconnecting device we know that support EATT. * Just connect CoC */ LOG(INFO) << __func__ << " Known device, connect eCoC"; connect_eatt(eatt_dev); return; } /* For new device, first check if EATT is supported. */ if (gatt_profile_get_eatt_support( bd_addr, base::BindOnce(&eatt_impl::eatt_is_supported_cb, base::Unretained(this))) == false) { /* For new device, first read GATT server supported features. */ if (gatt_cl_read_sr_supp_feat_req( bd_addr, base::BindOnce(&eatt_impl::supported_features_cb, base::Unretained(this), role)) == false) { LOG(INFO) << __func__ << "Eatt is not supported. Checked for device " << bd_addr; } Loading
system/stack/gatt/gatt_attr.cc +52 −37 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include "bt_target.h" #include "bt_utils.h" #include "btif/include/btif_storage.h" #include "eatt/eatt.h" #include "gatt_api.h" #include "gatt_int.h" #include "gd/common/init_flags.h" Loading @@ -47,11 +48,12 @@ using bluetooth::Uuid; #define BLE_GATT_CL_ANDROID_SUP_FEAT \ (BLE_GATT_CL_SUP_FEAT_EATT_BITMASK | BLE_GATT_CL_SUP_FEAT_MULTI_NOTIF_BITMASK) using gatt_eatt_support_cb = base::OnceCallback<void(const RawAddress&, bool)>; using gatt_sr_supported_feat_cb = base::OnceCallback<void(const RawAddress&, uint8_t)>; typedef struct { uint16_t op_uuid; gatt_eatt_support_cb cb; gatt_sr_supported_feat_cb cb; } gatt_op_cb_data; static std::map<uint16_t, gatt_op_cb_data> OngoingOps; Loading Loading @@ -502,19 +504,6 @@ static void gatt_disc_cmpl_cback(uint16_t conn_id, tGATT_DISC_TYPE disc_type, gatt_cl_start_config_ccc(p_clcb); } static void gatt_attr_send_is_eatt_cb(uint16_t conn_id, gatt_op_cb_data* cb, bool eatt_supported) { tGATT_IF gatt_if; RawAddress bd_addr; tBT_TRANSPORT transport; GATT_GetConnectionInfor(conn_id, &gatt_if, bd_addr, &transport); std::move(cb->cb).Run(bd_addr, eatt_supported); cb->op_uuid = 0; } static bool gatt_svc_read_cl_supp_feat_req(uint16_t conn_id, gatt_op_cb_data* cb) { tGATT_READ_PARAM param; Loading Loading @@ -585,6 +574,7 @@ static void gatt_cl_op_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op, gatt_op_cb_data* operation_callback_data = &iter->second; uint16_t cl_op_uuid = operation_callback_data->op_uuid; operation_callback_data->op_uuid = 0; uint8_t* pp = p_data->att_value.value; Loading @@ -592,24 +582,24 @@ static void gatt_cl_op_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op, switch (cl_op_uuid) { case GATT_UUID_SERVER_SUP_FEAT: { uint8_t supported_feat_mask = 0; uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); tGATT_TCB& tcb = gatt_cb.tcb[tcb_idx]; /* Check if EATT is supported */ if (status == GATT_SUCCESS) { STREAM_TO_UINT8(supported_feat_mask, pp); STREAM_TO_UINT8(tcb.sr_supp_feat, pp); btif_storage_set_gatt_sr_supp_feat(tcb.peer_bda, tcb.sr_supp_feat); } /* Notify user if eatt is supported */ bool eatt_supported = supported_feat_mask & BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK; gatt_attr_send_is_eatt_cb(conn_id, operation_callback_data, eatt_supported); /* Notify user about the supported features */ std::move(operation_callback_data->cb) .Run(tcb.peer_bda, tcb.sr_supp_feat); /* If server supports EATT lets try to find handle for the * client supported features characteristic, where we could write * our supported features as a client. */ if (eatt_supported) { if (tcb.sr_supp_feat & BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK) { /* If read succeed, return here */ if (gatt_svc_read_cl_supp_feat_req(conn_id, operation_callback_data)) return; Loading Loading @@ -717,19 +707,46 @@ void GATT_ConfigServiceChangeCCC(const RawAddress& remote_bda, bool enable, /******************************************************************************* * * Function gatt_svc_read_supp_feat_req * Function gatt_cl_init_sr_status * * Description Restore status for trusted GATT Server device * * Returns none * ******************************************************************************/ void gatt_cl_init_sr_status(tGATT_TCB& tcb) { tcb.sr_supp_feat = btif_storage_get_sr_supp_feat(tcb.peer_bda); if (tcb.sr_supp_feat & BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK) bluetooth::eatt::EattExtension::AddFromStorage(tcb.peer_bda); } /******************************************************************************* * * Function gatt_cl_read_sr_supp_feat_req * * Description Read remote device supported GATT feature mask. * * Returns bool * ******************************************************************************/ static bool gatt_svc_read_supp_feat_req( const RawAddress& peer_bda, uint16_t conn_id, base::OnceCallback<void(const RawAddress&, bool)> cb) { bool gatt_cl_read_sr_supp_feat_req( const RawAddress& peer_bda, base::OnceCallback<void(const RawAddress&, uint8_t)> cb) { tGATT_PROFILE_CLCB* p_clcb; tGATT_READ_PARAM param; tGATT_PROFILE_CLCB* p_clcb = gatt_profile_find_clcb_by_conn_id(conn_id); uint16_t conn_id; if (!cb) return false; VLOG(1) << __func__ << " BDA: " << peer_bda << " read gatt supported features"; GATT_GetConnIdIfConnected(gatt_cb.gatt_if, peer_bda, &conn_id, BT_TRANSPORT_LE); if (conn_id == GATT_INVALID_CONN_ID) return false; p_clcb = gatt_profile_find_clcb_by_conn_id(conn_id); if (!p_clcb) { p_clcb = gatt_profile_clcb_alloc(conn_id, peer_bda, BT_TRANSPORT_LE); } Loading Loading @@ -773,18 +790,13 @@ static bool gatt_svc_read_supp_feat_req( * * Description Check if EATT is supported with remote device. * * Returns false in case read could not be sent. * Returns if EATT is supported. * ******************************************************************************/ bool gatt_profile_get_eatt_support( const RawAddress& remote_bda, base::OnceCallback<void(const RawAddress&, bool)> cb) { bool gatt_profile_get_eatt_support(const RawAddress& remote_bda) { uint16_t conn_id; if (!cb) return false; VLOG(1) << __func__ << " BDA: " << remote_bda << " read gatt supported features"; VLOG(1) << __func__ << " BDA: " << remote_bda << " read GATT support"; GATT_GetConnIdIfConnected(gatt_cb.gatt_if, remote_bda, &conn_id, BT_TRANSPORT_LE); Loading @@ -792,7 +804,10 @@ bool gatt_profile_get_eatt_support( /* This read is important only when connected */ if (conn_id == GATT_INVALID_CONN_ID) return false; return gatt_svc_read_supp_feat_req(remote_bda, conn_id, std::move(cb)); /* Get tcb info */ uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); tGATT_TCB& tcb = gatt_cb.tcb[tcb_idx]; return tcb.sr_supp_feat & BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK; } /******************************************************************************* Loading
system/stack/gatt/gatt_int.h +7 −3 Original line number Diff line number Diff line Loading @@ -317,6 +317,8 @@ typedef struct { // TODO(hylo): support byte array data /* Client supported feature*/ uint8_t cl_supp_feat; /* Server supported features */ uint8_t sr_supp_feat; /* Use for server. if false, should handle database out of sync. */ bool is_robust_cache_change_aware; Loading Loading @@ -459,9 +461,11 @@ extern void gatt_add_a_bonded_dev_for_srv_chg(const RawAddress& bda); /* from gatt_attr.cc */ extern uint16_t gatt_profile_find_conn_id_by_bd_addr(const RawAddress& bda); extern bool gatt_profile_get_eatt_support( const RawAddress& remote_bda, base::OnceCallback<void(const RawAddress&, bool)> cb); extern bool gatt_profile_get_eatt_support(const RawAddress& remote_bda); extern void gatt_cl_init_sr_status(tGATT_TCB& tcb); extern bool gatt_cl_read_sr_supp_feat_req( const RawAddress& peer_bda, base::OnceCallback<void(const RawAddress&, uint8_t)> cb); extern bool gatt_sr_is_cl_change_aware(tGATT_TCB& tcb); extern void gatt_sr_init_cl_status(tGATT_TCB& tcb); Loading